@@ -129,6 +129,7 @@ import '../fasta_codes.dart'
129
129
templateIncorrectTypeArgumentQualified,
130
130
templateIncorrectTypeArgumentQualifiedInferred,
131
131
templateIntersectionTypeAsTypeArgument,
132
+ templateLanguageVersionTooHigh,
132
133
templateLoadLibraryHidesMember,
133
134
templateLocalDefinitionHidesExport,
134
135
templateLocalDefinitionHidesImport,
@@ -312,6 +313,9 @@ class SourceLibraryBuilder extends LibraryBuilder {
312
313
313
314
bool languageVersionExplicitlySet = false ;
314
315
316
+ bool postponedProblemsIssued = false ;
317
+ List <PostponedProblem > postponedProblems;
318
+
315
319
SourceLibraryBuilder .internal (SourceLoader loader, Uri fileUri, Scope scope,
316
320
SourceLibraryBuilder actualOrigin, Library library, Library nameOrigin)
317
321
: this .fromScopes (loader, fileUri, new DeclarationBuilder .library (),
@@ -356,10 +360,26 @@ class SourceLibraryBuilder extends LibraryBuilder {
356
360
}
357
361
358
362
@override
359
- void setLanguageVersion (int major, int minor, {bool explicit}) {
363
+ void setLanguageVersion (int major, int minor,
364
+ {int offset: 0 , int length: noLength, bool explicit}) {
360
365
if (languageVersionExplicitlySet) return ;
361
- library.setLanguageVersion (major, minor);
362
366
if (explicit) languageVersionExplicitlySet = true ;
367
+
368
+ // If no language version has been set, the default is used.
369
+ // If trying to set a langauge version that is higher than the "already-set"
370
+ // version it's an error.
371
+ if (major > library.languageVersionMajor ||
372
+ (major == library.languageVersionMajor &&
373
+ minor > library.languageVersionMinor)) {
374
+ addPostponedProblem (
375
+ templateLanguageVersionTooHigh.withArguments (
376
+ library.languageVersionMajor, library.languageVersionMinor),
377
+ offset,
378
+ length,
379
+ fileUri);
380
+ return ;
381
+ }
382
+ library.setLanguageVersion (major, minor);
363
383
}
364
384
365
385
ConstructorReferenceBuilder addConstructorReference (Object name,
@@ -1105,6 +1125,33 @@ class SourceLibraryBuilder extends LibraryBuilder {
1105
1125
..bind (new VoidTypeBuilder (const VoidType (), this , charOffset));
1106
1126
}
1107
1127
1128
+ /// Add a problem that might not be reported immediately.
1129
+ ///
1130
+ /// Problems will be issued after source information has been added.
1131
+ /// Once the problems has been issued, adding a new "postponed" problem will
1132
+ /// be issued immediately.
1133
+ void addPostponedProblem (
1134
+ Message message, int charOffset, int length, Uri fileUri) {
1135
+ if (postponedProblemsIssued) {
1136
+ addProblem (message, charOffset, length, fileUri);
1137
+ } else {
1138
+ postponedProblems ?? = < PostponedProblem > [];
1139
+ postponedProblems
1140
+ .add (new PostponedProblem (message, charOffset, length, fileUri));
1141
+ }
1142
+ }
1143
+
1144
+ void issuePostponedProblems () {
1145
+ postponedProblemsIssued = true ;
1146
+ if (postponedProblems == null ) return ;
1147
+ for (int i = 0 ; i < postponedProblems.length; ++ i) {
1148
+ PostponedProblem postponedProblem = postponedProblems[i];
1149
+ addProblem (postponedProblem.message, postponedProblem.charOffset,
1150
+ postponedProblem.length, postponedProblem.fileUri);
1151
+ }
1152
+ postponedProblems = null ;
1153
+ }
1154
+
1108
1155
@override
1109
1156
FormattedMessage addProblem (
1110
1157
Message message, int charOffset, int length, Uri fileUri,
@@ -3026,3 +3073,12 @@ Uri computeLibraryUri(Declaration declaration) {
3026
3073
}
3027
3074
3028
3075
String extractName (name) => name is QualifiedName ? name.name : name;
3076
+
3077
+ class PostponedProblem {
3078
+ final Message message;
3079
+ final int charOffset;
3080
+ final int length;
3081
+ final Uri fileUri;
3082
+
3083
+ PostponedProblem (this .message, this .charOffset, this .length, this .fileUri);
3084
+ }
0 commit comments