[modular] Create repro of issue building full dills from summaries.

Change-Id: I67db9eefe508ddbe072238e8773109c7b7f25d1a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/222560
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Joshua Litt <joshualitt@google.com>
This commit is contained in:
Joshua Litt 2021-12-10 17:00:00 +00:00 committed by Commit Bot
parent 052fbd3103
commit 2da9688cfb
8 changed files with 121 additions and 45 deletions

View file

@ -344,8 +344,8 @@ abstract class Compiler {
}
frontendStrategy.registerModuleData(data);
// After we've deserialized modular data, we set and verify the main
// method as well as trim the component of any unnecessary dependencies.
// After we've deserialized modular data, we trim the component of any
// unnecessary dependencies.
// Note: It is critical we wait to trim the dill until after we've
// deserialized modular data because some of this data may reference
// 'trimmed' elements.
@ -354,14 +354,7 @@ abstract class Compiler {
dumpUnusedLibraries(result);
}
if (options.entryUri != null) {
result.setMainAndTrimComponent(options.entryUri);
}
if (result.component.mainMethod == null) {
// TODO(sigmund): move this so that we use the same error template
// from the CFE.
_reporter.reportError(_reporter.createMessage(NO_LOCATION_SPANNABLE,
MessageKind.GENERIC, {'text': "No 'main' method found."}));
return;
result.trimComponent(options.entryUri);
}
}
if (options.cfeOnly) {

View file

@ -52,6 +52,37 @@ class KernelLoaderTask extends CompilerTask {
@override
String get name => 'kernel loader';
static Library _findEntryLibrary(Component component, Uri entryUri) {
var entryLibrary = component.libraries
.firstWhere((l) => l.fileUri == entryUri, orElse: () => null);
if (entryLibrary == null) {
throw ArgumentError('Entry uri $entryUri not found in dill.');
}
return entryLibrary;
}
static ir.Reference _findMainMethod(Library entryLibrary) {
var mainMethod = entryLibrary.procedures
.firstWhere((p) => p.name.text == 'main', orElse: () => null);
// In some cases, a main method is defined in another file, and then
// exported. In these cases, we search for the main method in
// [additionalExports].
ir.Reference mainMethodReference;
if (mainMethod == null) {
mainMethodReference = entryLibrary.additionalExports.firstWhere(
(p) => p.canonicalName.name == 'main',
orElse: () => null);
} else {
mainMethodReference = mainMethod.reference;
}
if (mainMethodReference == null) {
throw ArgumentError(
'Entry uri ${entryLibrary.fileUri} has no main method.');
}
return mainMethodReference;
}
/// Loads an entire Kernel [Component] from a file on disk.
Future<KernelResult> load() {
return measure(() async {
@ -128,6 +159,18 @@ class KernelLoaderTask extends CompilerTask {
await read(dependency);
}
}
if (_options.entryUri != null) {
var entryLibrary = _findEntryLibrary(component, _options.entryUri);
var mainMethod = _findMainMethod(entryLibrary);
component.setMainMethodAndMode(mainMethod, true, component.mode);
}
if (!_options.modularMode && component.mainMethod == null) {
// TODO(sigmund): move this so that we use the same error template
// from the CFE.
_reporter.reportError(_reporter.createMessage(NO_LOCATION_SPANNABLE,
MessageKind.GENERIC, {'text': "No 'main' method found."}));
}
} else {
bool verbose = false;
Target target =
@ -250,40 +293,7 @@ class KernelResult {
KernelResult(this.component, this.rootLibraryUri, this.libraries,
this.moduleLibraries);
static Library _findEntryLibrary(Component component, Uri entryUri) {
var entryLibrary = component.libraries
.firstWhere((l) => l.fileUri == entryUri, orElse: () => null);
if (entryLibrary == null) {
throw ArgumentError('Entry uri $entryUri not found in dill.');
}
return entryLibrary;
}
static ir.Reference _findMainMethod(Library entryLibrary) {
var mainMethod = entryLibrary.procedures
.firstWhere((p) => p.name.text == 'main', orElse: () => null);
// In some cases, a main method is defined in another file, and then
// exported. In these cases, we search for the main method in
// [additionalExports].
ir.Reference mainMethodReference;
if (mainMethod == null) {
mainMethodReference = entryLibrary.additionalExports.firstWhere(
(p) => p.canonicalName.name == 'main',
orElse: () => null);
} else {
mainMethodReference = mainMethod.reference;
}
if (mainMethodReference == null) {
throw ArgumentError(
'Entry uri ${entryLibrary.fileUri} has no main method.');
}
return mainMethodReference;
}
void setMainAndTrimComponent(Uri entryUri) {
var entryLibrary = _findEntryLibrary(component, entryUri);
var mainMethod = _findMainMethod(entryLibrary);
void trimComponent(Uri entryUri) {
var irLibraryMap = <Uri, Library>{};
var irLibraries = <Library>[];
for (var library in component.libraries) {
@ -292,11 +302,13 @@ class KernelResult {
for (var library in libraries) {
irLibraries.add(irLibraryMap[library]);
}
var mainMethod = component.mainMethodName;
var componentMode = component.mode;
component = ir.Component(
libraries: irLibraries,
uriToSource: component.uriToSource,
nameRoot: component.root);
component.setMainMethodAndMode(mainMethod, true, component.mode);
component.setMainMethodAndMode(mainMethod, true, componentMode);
}
@override

View file

@ -0,0 +1,25 @@
// Copyright (c) 2021, 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 't.dart';
String _defaultStringy(String t) => t.toLowerCase();
class A {
A({
double d = 3.14,
StringyFunction<String> s = _defaultStringy,
}) : this.factoryConstructor(d: d, s: s);
A.factoryConstructor({
double d = 3.14,
StringyFunction<String> s = _defaultStringy,
}) : d = d,
_s = s;
String doStringy(String i) => _s(i);
final double d;
final StringyFunction<String> _s;
}

View file

@ -0,0 +1,10 @@
// Copyright (c) 2020, 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 'a.dart';
import 'm.dart';
class B extends A with M {
B({double d = 2.71}) : super(d: d);
}

View file

@ -0,0 +1,9 @@
// Copyright (c) 2021, 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 'a.dart';
mixin M on A {
m1() {}
}

View file

@ -0,0 +1,13 @@
// Copyright (c) 2021, 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:expect/expect.dart';
import 'b.dart';
main() {
var bInst = B();
Expect.equals(2.71, bInst.d);
Expect.equals('default', bInst.doStringy('DEFAULT'));
}

View file

@ -0,0 +1,9 @@
# Copyright (c) 2021, 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.
dependencies:
main: [a, b, m, expect]
b: [a, m]
m: a
a: t

View file

@ -0,0 +1,5 @@
// Copyright (c) 2021, 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.
typedef StringyFunction<T> = String Function(T item);