Error on re-export, export and import of libraries with same name.

Fixes #12916.

Change-Id: Icef0f04f1575c8dad5f1cd23a9363f06fa2a2b35
Reviewed-on: https://dart-review.googlesource.com/74161
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Peter von der Ahé <ahe@google.com>
This commit is contained in:
Jens Johansen 2018-09-25 09:09:21 +00:00 committed by commit-bot@chromium.org
parent 4b312b2b8c
commit 570fd5a788
17 changed files with 243 additions and 16 deletions

View file

@ -98,7 +98,8 @@ abstract class LibraryBuilder<T extends TypeBuilder, R>
}
/// Returns true if the export scope was modified.
bool addToExportScope(String name, Declaration member) {
bool addToExportScope(String name, Declaration member,
[int charOffset = -1]) {
if (name.startsWith("_")) return false;
if (member is PrefixBuilder) return false;
Map<String, Declaration> map =
@ -107,7 +108,7 @@ abstract class LibraryBuilder<T extends TypeBuilder, R>
if (existing == member) return false;
if (existing != null) {
Declaration result = computeAmbiguousDeclaration(
name, existing, member, -1,
name, existing, member, charOffset,
isExport: true);
map[name] = result;
return result != existing;

View file

@ -30,6 +30,6 @@ class Export {
if (combinator.isHide && combinator.names.contains(name)) return false;
}
}
return exporter.addToExportScope(name, member);
return exporter.addToExportScope(name, member, charOffset);
}
}

View file

@ -2049,7 +2049,7 @@ const Code<Message Function(String name, Uri uri_, Uri uri2_)>
codeDuplicatedExport =
const Code<Message Function(String name, Uri uri_, Uri uri2_)>(
"DuplicatedExport", templateDuplicatedExport,
analyzerCode: "AMBIGUOUS_EXPORT", severity: Severity.ignored);
analyzerCode: "AMBIGUOUS_EXPORT");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsDuplicatedExport(String name, Uri uri_, Uri uri2_) {
@ -2133,6 +2133,86 @@ Message _withArgumentsDuplicatedImportInType(String name, Uri uri_, Uri uri2_) {
arguments: {'name': name, 'uri': uri_, 'uri2': uri2_});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)> templateDuplicatedLibraryExport =
const Template<Message Function(String name)>(
messageTemplate:
r"""A library with name '#name' is exported more than once.""",
withArguments: _withArgumentsDuplicatedLibraryExport);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name)> codeDuplicatedLibraryExport =
const Code<Message Function(String name)>(
"DuplicatedLibraryExport", templateDuplicatedLibraryExport,
analyzerCode: "EXPORT_DUPLICATED_LIBRARY_NAMED");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsDuplicatedLibraryExport(String name) {
return new Message(codeDuplicatedLibraryExport,
message: """A library with name '${name}' is exported more than once.""",
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)>
templateDuplicatedLibraryExportContext =
const Template<Message Function(String name)>(
messageTemplate: r"""'#name' is also exported here.""",
withArguments: _withArgumentsDuplicatedLibraryExportContext);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name)> codeDuplicatedLibraryExportContext =
const Code<Message Function(String name)>("DuplicatedLibraryExportContext",
templateDuplicatedLibraryExportContext,
severity: Severity.context);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsDuplicatedLibraryExportContext(String name) {
return new Message(codeDuplicatedLibraryExportContext,
message: """'${name}' is also exported here.""",
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)> templateDuplicatedLibraryImport =
const Template<Message Function(String name)>(
messageTemplate:
r"""A library with name '#name' is imported more than once.""",
withArguments: _withArgumentsDuplicatedLibraryImport);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name)> codeDuplicatedLibraryImport =
const Code<Message Function(String name)>(
"DuplicatedLibraryImport", templateDuplicatedLibraryImport,
analyzerCode: "IMPORT_DUPLICATED_LIBRARY_NAMED");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsDuplicatedLibraryImport(String name) {
return new Message(codeDuplicatedLibraryImport,
message: """A library with name '${name}' is imported more than once.""",
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)>
templateDuplicatedLibraryImportContext =
const Template<Message Function(String name)>(
messageTemplate: r"""'#name' is also imported here.""",
withArguments: _withArgumentsDuplicatedLibraryImportContext);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name)> codeDuplicatedLibraryImportContext =
const Code<Message Function(String name)>("DuplicatedLibraryImportContext",
templateDuplicatedLibraryImportContext,
severity: Severity.context);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsDuplicatedLibraryImportContext(String name) {
return new Message(codeDuplicatedLibraryImportContext,
message: """'${name}' is also imported here.""",
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(Token token)> templateDuplicatedModifier =
const Template<Message Function(Token token)>(

View file

@ -49,6 +49,8 @@ import '../builder/builder.dart'
import '../export.dart' show Export;
import '../import.dart' show Import;
import '../fasta_codes.dart'
show
LocatedMessage,
@ -60,6 +62,10 @@ import '../fasta_codes.dart'
templateAmbiguousSupertypes,
templateCantReadFile,
templateCyclicClassHierarchy,
templateDuplicatedLibraryExport,
templateDuplicatedLibraryExportContext,
templateDuplicatedLibraryImport,
templateDuplicatedLibraryImportContext,
templateExtendingEnum,
templateExtendingRestricted,
templateIllegalMixin,
@ -650,6 +656,80 @@ class SourceLoader<L> extends Loader<L> {
}
}
ticker.logMs("Checked restricted supertypes");
// Check imports and exports for duplicate names.
// This is rather silly, e.g. it makes importing 'foo' and exporting another
// 'foo' ok.
builders.forEach((Uri uri, LibraryBuilder library) {
if (library is SourceLibraryBuilder && library.loader == this) {
// Check exports.
if (library.exports.isNotEmpty) {
Map<String, List<Export>> nameToExports;
bool errorExports = false;
for (Export export in library.exports) {
String name = export.exported?.name ?? '';
if (name != '') {
nameToExports ??= new Map<String, List<Export>>();
List<Export> exports = nameToExports[name] ??= <Export>[];
exports.add(export);
if (exports[0].exported != export.exported) errorExports = true;
}
}
if (errorExports) {
for (String name in nameToExports.keys) {
List<Export> exports = nameToExports[name];
if (exports.length < 2) continue;
List<LocatedMessage> context = <LocatedMessage>[];
for (Export export in exports.skip(1)) {
context.add(templateDuplicatedLibraryExportContext
.withArguments(name)
.withLocation(uri, export.charOffset, noLength));
}
library.addProblem(
templateDuplicatedLibraryExport.withArguments(name),
exports[0].charOffset,
noLength,
uri,
context: context);
}
}
}
// Check imports.
if (library.imports.isNotEmpty) {
Map<String, List<Import>> nameToImports;
bool errorImports;
for (Import import in library.imports) {
String name = import.imported?.name ?? '';
if (name != '') {
nameToImports ??= new Map<String, List<Import>>();
List<Import> imports = nameToImports[name] ??= <Import>[];
imports.add(import);
if (imports[0].imported != import.imported) errorImports = true;
}
}
if (errorImports != null) {
for (String name in nameToImports.keys) {
List<Import> imports = nameToImports[name];
if (imports.length < 2) continue;
List<LocatedMessage> context = <LocatedMessage>[];
for (Import import in imports.skip(1)) {
context.add(templateDuplicatedLibraryImportContext
.withArguments(name)
.withLocation(uri, import.charOffset, noLength));
}
library.addProblem(
templateDuplicatedLibraryImport.withArguments(name),
imports[0].charOffset,
noLength,
uri,
context: context);
}
}
}
}
});
ticker.logMs("Checked imports and exports for duplicate names");
}
void buildComponent() {

View file

@ -1577,8 +1577,23 @@ PrefixAfterCombinator:
DuplicatedExport:
template: "'#name' is exported from both '#uri' and '#uri2'."
severity: IGNORED
analyzerCode: AMBIGUOUS_EXPORT
script:
lib1.dart: "class A {}"
lib2.dart: "class A {}"
main.dart: "export 'lib1.dart'; export 'lib2.dart';"
DuplicatedLibraryExport:
template: "A library with name '#name' is exported more than once."
analyzerCode: EXPORT_DUPLICATED_LIBRARY_NAMED
script:
lib1.dart: "library foo;"
lib2.dart: "library foo;"
main.dart: "export 'lib1.dart'; export 'lib2.dart';"
DuplicatedLibraryExportContext:
template: "'#name' is also exported here."
severity: CONTEXT
DuplicatedExportInType:
template: "'#name' is exported from both '#uri' and '#uri2'."
@ -1588,6 +1603,18 @@ DuplicatedImport:
template: "'#name' is imported from both '#uri' and '#uri2'."
severity: IGNORED
DuplicatedLibraryImport:
template: "A library with name '#name' is imported more than once."
analyzerCode: IMPORT_DUPLICATED_LIBRARY_NAMED
script:
lib1.dart: "library foo;"
lib2.dart: "library foo;"
main.dart: "import 'lib1.dart'; import 'lib2.dart';"
DuplicatedLibraryImportContext:
template: "'#name' is also imported here."
severity: CONTEXT
DuplicatedImportInType:
template: "'#name' is imported from both '#uri' and '#uri2'."
severity: ERROR_LEGACY_WARNING

View file

@ -1,3 +1,15 @@
// Formatted problems:
//
// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
// export 'map.dart' show main;
// ^
// Unhandled errors:
//
// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
// export 'map.dart' show main;
// ^
library;
import self as self;

View file

@ -1,3 +1,9 @@
// Unhandled errors:
//
// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
// export 'map.dart' show main;
// ^
library;
import self as self;

View file

@ -1,3 +1,9 @@
// Formatted problems:
//
// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
// export 'map.dart' show main;
// ^
library;
import self as self;

View file

@ -1,3 +1,15 @@
// Formatted problems:
//
// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
// export 'map.dart' show main;
// ^
// Unhandled errors:
//
// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
// export 'map.dart' show main;
// ^
library;
import self as self;

View file

@ -1,3 +1,9 @@
// Unhandled errors:
//
// pkg/front_end/testcases/ambiguous_exports.dart:7:1: Error: 'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.
// export 'map.dart' show main;
// ^
library;
import self as self;

View file

@ -909,6 +909,8 @@ Utils/tests/Expect/identical_A01_t01: CompileTimeError # Uses Dart 1 constants
Utils/tests/Expect/setEquals_A01_t02: CompileTimeError # Uses Dart 1 constants
[ !$strong ]
Language/Libraries_and_Scripts/Exports/reexport_t01: MissingCompileTimeError
Language/Libraries_and_Scripts/Exports/reexport_t02: MissingCompileTimeError
LibTest/async/Stream/Stream.fromIterable_A02_t01: RuntimeError # Assumes no close after error.
LibTest/async/Stream/firstWhere_A01_t01: RuntimeError # co19 issue 137
LibTest/async/Stream/firstWhere_A02_t01: RuntimeError # co19 issue 137

View file

@ -11,6 +11,8 @@ Language/Expressions/Method_Invocation/Ordinary_Invocation/function_type_t01: Co
Language/Expressions/Method_Invocation/Ordinary_Invocation/static_type_t01: CompileTimeError # Expects a warning, but this is an error in Dart 2
Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
Language/Libraries_and_Scripts/Exports/same_name_t01: CompileTimeError # Expects a warning, but this is an error in Dart 2
Language/Libraries_and_Scripts/Imports/library_name_t01: CompileTimeError # Expects a warning, but this is an error in Dart 2
Language/Types/Parameterized_Types/arity_mismatch_t01: CompileTimeError
Language/Types/Parameterized_Types/arity_mismatch_t05: CompileTimeError
Language/Types/Parameterized_Types/arity_mismatch_t07: CompileTimeError
@ -920,7 +922,6 @@ Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t06: CompileTimeError
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t07: CompileTimeError
Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_getters_type_t08: CompileTimeError
Language/Libraries_and_Scripts/Exports/reexport_t01: MissingCompileTimeError
Language/Libraries_and_Scripts/Exports/show_hide_t01: CompileTimeError
Language/Libraries_and_Scripts/Exports/show_hide_t02: CompileTimeError
Language/Libraries_and_Scripts/Exports/syntax_t02: CompileTimeError

View file

@ -113,8 +113,7 @@ Language/Generics/scope_t06: MissingCompileTimeError # Issue 33308
Language/Generics/syntax_t02: CompileTimeError
Language/Generics/syntax_t03: CompileTimeError
Language/Generics/upper_bound_t01: MissingCompileTimeError # Issue 33308
Language/Libraries_and_Scripts/Exports/reexport_t01: MissingCompileTimeError # Issue 12916
Language/Libraries_and_Scripts/Exports/same_name_t01: MissingCompileTimeError # Issue 12916
Language/Libraries_and_Scripts/Imports/library_name_t01: CompileTimeError # Test is wrong. Spec says error not warning.
Language/Mixins/Mixin_Application/deferred_t01: MissingCompileTimeError # Issue 30273
Language/Mixins/Mixin_Application/static_warning_t01: MissingCompileTimeError # Mixin super equirement
Language/Mixins/Mixin_Application/syntax_t21: CompileTimeError # The test even says in the comment it should be a compile time error

View file

@ -25,6 +25,7 @@ inference/simple_inferrer_global_field_closure_test: Fail # Issue 16507
inference/swarm_test: Slow, Pass, Fail #
inference/type_mask2_test: RuntimeError # Issue 34095
inlining/inlining_test: Slow, Pass
model/in_user_code_test: RuntimeError # Two libraries with the same name -- actually a CompileTimeError
model/native_test: Pass, Slow
model/no_such_method_enabled_test: Pass, Slow
model/subtype_test: Pass, Slow

View file

@ -285,7 +285,6 @@ deferred_load_library_wrong_args_test/01: CompileTimeError
double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddk
dynamic_prefix_core_test/none: CompileTimeError
emit_const_fields_test: CompileTimeError # Issue 31533
export_ambiguous_main_test: MissingCompileTimeError
external_test/21: CompileTimeError
external_test/24: CompileTimeError
function_propagation_test: RuntimeError

View file

@ -234,7 +234,6 @@ constructor_reference_test/27: MissingCompileTimeError # Issue 34403
deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
duplicate_export_collision_test/01: MissingCompileTimeError # Issue 12916
f_bounded_quantification_test/01: MissingCompileTimeError # Issue 33308
f_bounded_quantification_test/02: MissingCompileTimeError # Issue 33308
generic_methods_bounds_test/01: MissingCompileTimeError # Issue 33308
@ -336,9 +335,6 @@ vm/debug_break_enabled_vm_test/01: CompileTimeError # KernelVM bug: Bad test usi
vm/debug_break_enabled_vm_test/none: CompileTimeError # KernelVM bug: Bad test using extended break syntax.
vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk && $runtime == vm && $strong ]
export_ambiguous_main_test: Crash # Issue 32618
[ $compiler == app_jitk && $mode == product ]
vm/causal_async_exception_stack2_test: RuntimeError
vm/causal_async_exception_stack_test: RuntimeError
@ -767,7 +763,6 @@ constants_test/05: MissingCompileTimeError
deferred_load_library_wrong_args_test/01: CompileTimeError
dynamic_prefix_core_test/none: CompileTimeError
emit_const_fields_test: CompileTimeError
export_ambiguous_main_test: MissingCompileTimeError
external_test/21: CompileTimeError
external_test/24: CompileTimeError
generic_methods_generic_function_result_test/01: MissingCompileTimeError
@ -1487,7 +1482,6 @@ dynamic_prefix_core_test/01: MissingCompileTimeError
empty_block_case_test: MissingCompileTimeError
enum_private_test/02: MissingCompileTimeError
error_stacktrace_test/00: MissingCompileTimeError
export_ambiguous_main_test: MissingCompileTimeError
external_test/21: CompileTimeError
external_test/24: CompileTimeError
factory1_test/00: MissingCompileTimeError

View file

@ -26,6 +26,7 @@ isolate/spawn_function_custom_class_test: Skip # Timeout
html/*: Skip # TODO(ahe): Make dart:html available.
isolate/browser/*: Skip # TODO(ahe): Make dart:html available.
js/*: Skip # TODO(ahe): Make dart:js available.
mirrors/repeated_private_anon_mixin_app_test: CompileTimeError # Two libraries with same name inported.
[ $fasta ]
mirrors/deferred_constraints_constants_test/default_argument2: MissingCompileTimeError
@ -204,7 +205,7 @@ mirrors/regress_26187_test: RuntimeError
mirrors/relation_assignable_test: RuntimeError
mirrors/relation_subclass_test: RuntimeError
mirrors/relation_subtype_test: RuntimeError
mirrors/repeated_private_anon_mixin_app_test: RuntimeError
mirrors/repeated_private_anon_mixin_app_test: CompileTimeError # Two libraries with same name inported.
mirrors/static_members_easier_test: RuntimeError # Issue 31402 (Invocation arguments)
mirrors/static_members_test: RuntimeError # Issue 31402 (Invocation arguments)
mirrors/symbol_validation_test/01: RuntimeError # Issue 31537