[frontend] report transformation error messages through library loader
Change-Id: I7280d02e42785742fc800f7e44b1913408dcada5
Reviewed-on: https://dart-review.googlesource.com/c/90460
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index 9ab34db..7b2863e 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -74,8 +74,12 @@
bool get errorOnUnexactWebIntLiterals => true;
@override
- void performModularTransformationsOnLibraries(ir.Component component,
- CoreTypes coreTypes, ClassHierarchy hierarchy, List<ir.Library> libraries,
+ void performModularTransformationsOnLibraries(
+ ir.Component component,
+ CoreTypes coreTypes,
+ ClassHierarchy hierarchy,
+ List<ir.Library> libraries,
+ DiagnosticReporter diagnosticReporter,
{void logger(String msg)}) {}
@override
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index 19891b3..7b56f28 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -13,7 +13,7 @@
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
import 'package:kernel/kernel.dart' hide LibraryDependency, Combinator;
-import 'package:kernel/target/targets.dart';
+import 'package:kernel/target/targets.dart' hide DiagnosticReporter;
import '../../compiler_new.dart' as api;
import '../common/tasks.dart' show CompilerTask, Measurer;
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 8652983..fdabc09 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -70,8 +70,12 @@
bool get enableNoSuchMethodForwarders => true;
@override
- void performModularTransformationsOnLibraries(Component component,
- CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+ void performModularTransformationsOnLibraries(
+ Component component,
+ CoreTypes coreTypes,
+ ClassHierarchy hierarchy,
+ List<Library> libraries,
+ DiagnosticReporter diagnosticReporter,
{void logger(String msg)}) {
this.hierarchy = hierarchy;
for (var library in libraries) {
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 8ca86a7..6564a5b 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -51,7 +51,11 @@
templateConstEvalNegativeShift,
templateConstEvalNonConstantLiteral,
templateConstEvalNonConstantVariableGet,
- templateConstEvalZeroDivisor;
+ templateConstEvalZeroDivisor,
+ templateFfiAnnotationMissing,
+ templateFfiTypeInvalid,
+ templateFfiTypeMismatch,
+ templateFfiTypeOpaque;
export '../fasta/hybrid_file_system.dart' show HybridFileSystem;
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 43f48ce..d4a2582 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -3347,6 +3347,129 @@
-h Display this message (add -v for information about all options).""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String
+ name)> templateFfiAnnotationMissing = const Template<
+ Message Function(String name)>(
+ messageTemplate:
+ r"""Field '#name' is missing an annotation to declare its C++ type,dart:ffi structs (Pointer<Void>) cannot have regular Dart fields.""",
+ withArguments: _withArgumentsFfiAnnotationMissing);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeFfiAnnotationMissing =
+ const Code<Message Function(String name)>(
+ "FfiAnnotationMissing",
+ templateFfiAnnotationMissing,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiAnnotationMissing(String name) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ return new Message(codeFfiAnnotationMissing,
+ message:
+ """Field '${name}' is missing an annotation to declare its C++ type,dart:ffi structs (Pointer<Void>) cannot have regular Dart fields.""",
+ arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(DartType _type)> templateFfiTypeInvalid = const Template<
+ Message Function(DartType _type)>(
+ messageTemplate:
+ r"""Expected type '#type' to be a valid and instantiated subtype of '_NativeType'.""",
+ withArguments: _withArgumentsFfiTypeInvalid);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type)> codeFfiTypeInvalid =
+ const Code<Message Function(DartType _type)>(
+ "FfiTypeInvalid",
+ templateFfiTypeInvalid,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiTypeInvalid(DartType _type) {
+ TypeLabeler labeler = new TypeLabeler();
+ List<Object> typeParts = labeler.labelType(_type);
+ String type = typeParts.join();
+ return new Message(codeFfiTypeInvalid,
+ message:
+ """Expected type '${type}' to be a valid and instantiated subtype of '_NativeType'.""" +
+ labeler.originMessages,
+ arguments: {'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ DartType
+ _type3)> templateFfiTypeMismatch = const Template<
+ Message Function(DartType _type, DartType _type2, DartType _type3)>(
+ messageTemplate:
+ r"""Expected type '#type' to be '#type2', which is the Dart type corresponding to '#type3'.""",
+ withArguments: _withArgumentsFfiTypeMismatch);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type, DartType _type2, DartType _type3)>
+ codeFfiTypeMismatch = const Code<
+ Message Function(DartType _type, DartType _type2, DartType _type3)>(
+ "FfiTypeMismatch",
+ templateFfiTypeMismatch,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiTypeMismatch(
+ DartType _type, DartType _type2, DartType _type3) {
+ TypeLabeler labeler = new TypeLabeler();
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ List<Object> type3Parts = labeler.labelType(_type3);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ String type3 = type3Parts.join();
+ return new Message(codeFfiTypeMismatch,
+ message:
+ """Expected type '${type}' to be '${type2}', which is the Dart type corresponding to '${type3}'.""" +
+ labeler.originMessages,
+ arguments: {'type': _type, 'type2': _type2, 'type3': _type3});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String name,
+ DartType
+ _type)> templateFfiTypeOpaque = const Template<
+ Message Function(String name, DartType _type)>(
+ messageTemplate:
+ r"""Method '#name' cannot be called on something of type '#type' as this type is opaque.""",
+ withArguments: _withArgumentsFfiTypeOpaque);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, DartType _type)> codeFfiTypeOpaque =
+ const Code<Message Function(String name, DartType _type)>(
+ "FfiTypeOpaque",
+ templateFfiTypeOpaque,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsFfiTypeOpaque(String name, DartType _type) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ TypeLabeler labeler = new TypeLabeler();
+ List<Object> typeParts = labeler.labelType(_type);
+ String type = typeParts.join();
+ return new Message(codeFfiTypeOpaque,
+ message:
+ """Method '${name}' cannot be called on something of type '${type}' as this type is opaque.""" +
+ labeler.originMessages,
+ arguments: {'name': name, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeFieldInitializedOutsideDeclaringClass =
messageFieldInitializedOutsideDeclaringClass;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index fc4788c..96f4adb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -39,6 +39,8 @@
import 'package:kernel/type_algebra.dart' show substitute;
+import 'package:kernel/target/targets.dart' show DiagnosticReporter;
+
import 'package:kernel/type_environment.dart' show TypeEnvironment;
import 'package:kernel/transformations/constants.dart' as constants
@@ -54,6 +56,10 @@
import '../dill/dill_member_builder.dart' show DillMemberBuilder;
+import '../fasta_codes.dart' show Message, LocatedMessage;
+
+import '../loader.dart' show Loader;
+
import '../messages.dart'
show
FormattedMessage,
@@ -753,7 +759,11 @@
ticker.logMs("Evaluated constants");
}
backendTarget.performModularTransformationsOnLibraries(
- component, loader.coreTypes, loader.hierarchy, loader.libraries,
+ component,
+ loader.coreTypes,
+ loader.hierarchy,
+ loader.libraries,
+ new KernelDiagnosticReporter(loader),
logger: (String msg) => ticker.logMs(msg));
}
@@ -818,3 +828,15 @@
}
return null;
}
+
+class KernelDiagnosticReporter
+ extends DiagnosticReporter<Message, LocatedMessage> {
+ final Loader<Library> loader;
+
+ KernelDiagnosticReporter(this.loader);
+
+ void report(Message message, int charOffset, int length, Uri fileUri,
+ {List<LocatedMessage> context}) {
+ loader.addProblem(message, charOffset, noLength, fileUri, context: context);
+ }
+}
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 445d797..b88b3a1 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -173,6 +173,10 @@
FastaUsageLong/example: Fail
FastaUsageShort/analyzerCode: Fail
FastaUsageShort/example: Fail
+FfiAnnotationMissing/analyzerCode : Fail
+FfiTypeInvalid/analyzerCode: Fail
+FfiTypeMismatch/analyzerCode: Fail
+FfiTypeOpaque/analyzerCode: Fail
FieldInitializedOutsideDeclaringClass/script1: Fail
FieldInitializerOutsideConstructor/script1: Fail
FinalAndCovariant/script2: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 7b717b1..79f6350 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -3409,3 +3409,23 @@
StaticAndInstanceConflictCause:
template: "This is the instance member."
severity: CONTEXT
+
+FfiTypeMismatch:
+ # Used by dart:ffi
+ template: "Expected type '#type' to be '#type2', which is the Dart type corresponding to '#type3'."
+ external: test/ffi_test.dart
+
+FfiTypeInvalid:
+ # Used by dart:ffi
+ template: "Expected type '#type' to be a valid and instantiated subtype of '_NativeType'."
+ external: test/ffi_test.dart
+
+FfiTypeOpaque:
+ # Used by dart:ffi
+ template: "Method '#name' cannot be called on something of type '#type' as this type is opaque."
+ external: test/ffi_test.dart
+
+FfiAnnotationMissing:
+ # Used by dart:ffi
+ template: "Field '#name' is missing an annotation to declare its C++ type,dart:ffi structs (Pointer<Void>) cannot have regular Dart fields."
+ external: test/ffi_test.dart
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 02a8e3a..6689d9f 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -18,7 +18,8 @@
import 'package:kernel/kernel.dart' show loadComponentFromBytes;
-import 'package:kernel/target/targets.dart' show TargetFlags;
+import 'package:kernel/target/targets.dart'
+ show TargetFlags, DiagnosticReporter;
import 'package:testing/testing.dart'
show
@@ -423,12 +424,16 @@
String get name => "vm";
@override
- void performModularTransformationsOnLibraries(Component component,
- CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+ void performModularTransformationsOnLibraries(
+ Component component,
+ CoreTypes coreTypes,
+ ClassHierarchy hierarchy,
+ List<Library> libraries,
+ DiagnosticReporter diagnosticReporter,
{void logger(String msg)}) {
if (enabled) {
super.performModularTransformationsOnLibraries(
- component, coreTypes, hierarchy, libraries,
+ component, coreTypes, hierarchy, libraries, diagnosticReporter,
logger: logger);
}
}
diff --git a/pkg/front_end/test/ffi_test.dart b/pkg/front_end/test/ffi_test.dart
new file mode 100644
index 0000000..f032f75
--- /dev/null
+++ b/pkg/front_end/test/ffi_test.dart
@@ -0,0 +1,10 @@
+// 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:expect/expect.dart';
+
+main() {
+ // TODO(dacoharkes): implement dart:ffi tests
+ Expect.isTrue(true);
+}
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 007fc9e..f64802f 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -36,6 +36,11 @@
return builder(flags);
}
+abstract class DiagnosticReporter<M, C> {
+ void report(M message, int charOffset, int length, Uri fileUri,
+ {List<C> context});
+}
+
/// A target provides backend-specific options for generating kernel IR.
abstract class Target {
String get name;
@@ -94,8 +99,12 @@
void performOutlineTransformations(Component component) {}
/// Perform target-specific modular transformations on the given libraries.
- void performModularTransformationsOnLibraries(Component component,
- CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+ void performModularTransformationsOnLibraries(
+ Component component,
+ CoreTypes coreTypes,
+ ClassHierarchy hierarchy,
+ List<Library> libraries,
+ DiagnosticReporter diagnosticReporter,
{void logger(String msg)});
/// Perform target-specific modular transformations on the given program.
@@ -196,8 +205,12 @@
bool get legacyMode => flags.legacyMode;
String get name => 'none';
List<String> get extraRequiredLibraries => <String>[];
- void performModularTransformationsOnLibraries(Component component,
- CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+ void performModularTransformationsOnLibraries(
+ Component component,
+ CoreTypes coreTypes,
+ ClassHierarchy hierarchy,
+ List<Library> libraries,
+ DiagnosticReporter diagnosticReporter,
{void logger(String msg)}) {}
@override
diff --git a/pkg/vm/lib/target/vm.dart b/pkg/vm/lib/target/vm.dart
index a43e07c..0a33c87 100644
--- a/pkg/vm/lib/target/vm.dart
+++ b/pkg/vm/lib/target/vm.dart
@@ -68,8 +68,12 @@
];
@override
- void performModularTransformationsOnLibraries(Component component,
- CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
+ void performModularTransformationsOnLibraries(
+ Component component,
+ CoreTypes coreTypes,
+ ClassHierarchy hierarchy,
+ List<Library> libraries,
+ DiagnosticReporter diagnosticReporter,
{void logger(String msg)}) {
transformMixins.transformLibraries(this, coreTypes, hierarchy, libraries,
doSuperResolution: false /* resolution is done in Dart VM */);