Skip to content

Commit 849cdb2

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Check for consistency of language version overrides between library and parts.
Change-Id: I209cbcda3d96c4e2f1f7a0352b563c886a22e687 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153702 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent aff2260 commit 849cdb2

File tree

6 files changed

+179
-0
lines changed

6 files changed

+179
-0
lines changed

pkg/analyzer/lib/error/error.dart

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ const List<ErrorCode> errorCodeValues = [
180180
CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
181181
CompileTimeErrorCode.INCONSISTENT_INHERITANCE,
182182
CompileTimeErrorCode.INCONSISTENT_INHERITANCE_GETTER_AND_METHOD,
183+
CompileTimeErrorCode.INCONSISTENT_LANGUAGE_VERSION_OVERRIDE,
183184
CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
184185
CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
185186
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,

pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart

+40
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ class LibraryAnalyzer {
185185

186186
assert(units.values.every(LegacyTypeAsserter.assertLegacyTypes));
187187

188+
_checkForInconsistentLanguageVersionOverride(units);
189+
188190
timerLibraryAnalyzerVerify.stop();
189191

190192
// Return full results.
@@ -198,6 +200,44 @@ class LibraryAnalyzer {
198200
return results;
199201
}
200202

203+
void _checkForInconsistentLanguageVersionOverride(
204+
Map<FileState, CompilationUnit> units,
205+
) {
206+
var libraryUnit = units.values.first;
207+
var libraryOverrideToken = libraryUnit.languageVersionToken;
208+
209+
for (var partEntry in units.entries.skip(1)) {
210+
var partUnit = partEntry.value;
211+
var partOverrideToken = partUnit.languageVersionToken;
212+
if (libraryOverrideToken != null) {
213+
if (partOverrideToken != null) {
214+
if (partOverrideToken.major != libraryOverrideToken.major ||
215+
partOverrideToken.minor != libraryOverrideToken.minor) {
216+
_getErrorReporter(partEntry.key).reportErrorForToken(
217+
CompileTimeErrorCode.INCONSISTENT_LANGUAGE_VERSION_OVERRIDE,
218+
partOverrideToken,
219+
);
220+
}
221+
} else {
222+
var partDirectives = partUnit.directives;
223+
for (var partOf in partDirectives.whereType<PartOfDirective>()) {
224+
var partOffset = partOf.partKeyword.offset;
225+
_getErrorReporter(partEntry.key).reportErrorForOffset(
226+
CompileTimeErrorCode.INCONSISTENT_LANGUAGE_VERSION_OVERRIDE,
227+
partOffset,
228+
partOf.ofKeyword.end - partOffset,
229+
);
230+
}
231+
}
232+
} else if (partOverrideToken != null) {
233+
_getErrorReporter(partEntry.key).reportErrorForToken(
234+
CompileTimeErrorCode.INCONSISTENT_LANGUAGE_VERSION_OVERRIDE,
235+
partOverrideToken,
236+
);
237+
}
238+
}
239+
}
240+
201241
void _computeConstantErrors(
202242
ErrorReporter errorReporter, CompilationUnit unit) {
203243
ConstantVerifier constantVerifier = ConstantVerifier(

pkg/analyzer/lib/src/error/codes.dart

+14
Original file line numberDiff line numberDiff line change
@@ -3032,6 +3032,20 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
30323032
"Try adjusting the supertypes of this class to remove the "
30333033
"inconsistency.");
30343034

3035+
/**
3036+
* It is a compile-time error if a part file has a different language version
3037+
* override than its library.
3038+
*
3039+
* https://github.com/dart-lang/language/blob/master/accepted/
3040+
* future-releases/language-versioning/feature-specification.md
3041+
* #individual-library-language-version-override
3042+
*/
3043+
static const CompileTimeErrorCode INCONSISTENT_LANGUAGE_VERSION_OVERRIDE =
3044+
CompileTimeErrorCode(
3045+
'INCONSISTENT_LANGUAGE_VERSION_OVERRIDE',
3046+
"Parts must have exactly the same language version override as "
3047+
"the library.");
3048+
30353049
/**
30363050
* Parameters:
30373051
* 0: the name of the initializing formal that is not an instance variable in

pkg/analyzer/test/src/dart/resolution/resolution.dart

+10
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,16 @@ mixin ResolutionTest implements ResourceProviderMixin {
257257
return result;
258258
}
259259

260+
Future<void> assertErrorsInFile2(
261+
String path,
262+
List<ExpectedError> expectedErrors,
263+
) async {
264+
path = convertPath(path);
265+
266+
var result = await resolveFile(path);
267+
assertErrorsInResolvedUnit(result, expectedErrors);
268+
}
269+
260270
void assertErrorsInList(
261271
List<AnalysisError> errors,
262272
List<ExpectedError> expectedErrors,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analyzer/src/error/codes.dart';
6+
import 'package:meta/meta.dart';
7+
import 'package:test_reflective_loader/test_reflective_loader.dart';
8+
9+
import '../../generated/test_support.dart';
10+
import '../dart/resolution/driver_resolution.dart';
11+
12+
main() {
13+
defineReflectiveSuite(() {
14+
defineReflectiveTests(InconsistentLanguageVersionOverrideTest);
15+
});
16+
}
17+
18+
@reflectiveTest
19+
class InconsistentLanguageVersionOverrideTest extends DriverResolutionTest {
20+
CompileTimeErrorCode get _errorCode =>
21+
CompileTimeErrorCode.INCONSISTENT_LANGUAGE_VERSION_OVERRIDE;
22+
23+
test_both_different() async {
24+
await _checkLibraryAndPart(
25+
libraryContent: r'''
26+
// @dart = 2.5
27+
part 'b.dart';
28+
''',
29+
partContent: r'''
30+
// @dart = 2.6
31+
part of 'a.dart';
32+
''',
33+
partErrors: [
34+
error(_errorCode, 0, 14),
35+
],
36+
);
37+
}
38+
39+
test_both_same() async {
40+
await _checkLibraryAndPart(
41+
libraryContent: r'''
42+
// @dart = 2.5
43+
part 'b.dart';
44+
''',
45+
partContent: r'''
46+
// @dart = 2.5
47+
part of 'a.dart';
48+
''',
49+
partErrors: [],
50+
);
51+
}
52+
53+
test_none() async {
54+
await _checkLibraryAndPart(
55+
libraryContent: r'''
56+
part 'b.dart';
57+
''',
58+
partContent: r'''
59+
part of 'a.dart';
60+
''',
61+
partErrors: [],
62+
);
63+
}
64+
65+
test_onlyLibrary() async {
66+
await _checkLibraryAndPart(
67+
libraryContent: r'''
68+
// @dart = 2.5
69+
part 'b.dart';
70+
''',
71+
partContent: r'''
72+
part of 'a.dart';
73+
''',
74+
partErrors: [
75+
error(_errorCode, 0, 7),
76+
],
77+
);
78+
}
79+
80+
test_onlyPart() async {
81+
await _checkLibraryAndPart(
82+
libraryContent: r'''
83+
part 'b.dart';
84+
''',
85+
partContent: r'''
86+
// @dart = 2.5
87+
part of 'a.dart';
88+
''',
89+
partErrors: [
90+
error(_errorCode, 0, 14),
91+
],
92+
);
93+
}
94+
95+
Future<void> _checkLibraryAndPart({
96+
@required String libraryContent,
97+
@required String partContent,
98+
@required List<ExpectedError> partErrors,
99+
}) async {
100+
var libraryPath = convertPath('/test/lib/a.dart');
101+
var partPath = convertPath('/test/lib/b.dart');
102+
103+
newFile(libraryPath, content: libraryContent);
104+
105+
newFile(partPath, content: partContent);
106+
107+
await resolveFile(libraryPath);
108+
109+
await assertErrorsInFile2(partPath, partErrors);
110+
}
111+
}

pkg/analyzer/test/src/diagnostics/test_all.dart

+3
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ import 'inconsistent_case_expression_types_test.dart'
191191
import 'inconsistent_inheritance_getter_and_method_test.dart'
192192
as inconsistent_inheritance_getter_and_method;
193193
import 'inconsistent_inheritance_test.dart' as inconsistent_inheritance;
194+
import 'inconsistent_language_version_override_test.dart'
195+
as inconsistent_language_version_override;
194196
import 'inference_failure_on_collection_literal_test.dart'
195197
as inference_failure_on_collection_literal;
196198
import 'inference_failure_on_function_return_type_test.dart'
@@ -663,6 +665,7 @@ main() {
663665
inconsistent_case_expression_types.main();
664666
inconsistent_inheritance_getter_and_method.main();
665667
inconsistent_inheritance.main();
668+
inconsistent_language_version_override.main();
666669
inference_failure_on_collection_literal.main();
667670
inference_failure_on_function_return_type.main();
668671
inference_failure_on_uninitialized_variable.main();

0 commit comments

Comments
 (0)