Skip to content

Commit 8c9a469

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe] Only create instantiation+invocation in implicit creation context
Closes #47069 Closes #47071 Closes #47075 Closes #47079 Change-Id: Icb7a45560d736f0fe50525e0c735450a0a3d9ff0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212281 Reviewed-by: Dmitry Stefantsov <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent a6cc772 commit 8c9a469

39 files changed

+809
-339
lines changed

Diff for: pkg/front_end/lib/src/fasta/kernel/body_builder.dart

+12-9
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
695695
push(arguments);
696696
_buildConstructorReferenceInvocation(
697697
beginToken.next!, beginToken.offset, Constness.explicitConst,
698-
inMetadata: true);
698+
inMetadata: true, inImplicitCreationContext: false);
699699
push(popForValue());
700700
} else {
701701
pop(); // Name last identifier
@@ -4792,12 +4792,12 @@ class BodyBuilder extends ScopeListener<JumpTarget>
47924792
debugEvent("NewExpression");
47934793
_buildConstructorReferenceInvocation(
47944794
token.next!, token.offset, Constness.explicitNew,
4795-
inMetadata: false);
4795+
inMetadata: false, inImplicitCreationContext: false);
47964796
}
47974797

47984798
void _buildConstructorReferenceInvocation(
47994799
Token nameToken, int offset, Constness constness,
4800-
{required bool inMetadata}) {
4800+
{required bool inMetadata, required bool inImplicitCreationContext}) {
48014801
assert(checkState(nameToken, [
48024802
/*arguments*/ ValueKinds.Arguments,
48034803
/*constructor name identifier*/ ValueKinds.IdentifierOrNull,
@@ -4828,15 +4828,17 @@ class BodyBuilder extends ScopeListener<JumpTarget>
48284828
ConstantContext savedConstantContext = pop() as ConstantContext;
48294829
if (type is Generator) {
48304830
push(type.invokeConstructor(
4831-
typeArguments, name, arguments, nameToken, nameLastToken, constness));
4831+
typeArguments, name, arguments, nameToken, nameLastToken, constness,
4832+
inImplicitCreationContext: inImplicitCreationContext));
48324833
} else if (type is ParserRecovery) {
48334834
push(new ParserErrorGenerator(
48344835
this, nameToken, fasta.messageSyntheticToken));
48354836
} else if (type is Expression) {
48364837
push(createInstantiationAndInvocation(
48374838
() => type, typeArguments, name, name, arguments,
48384839
instantiationOffset: offset,
4839-
invocationOffset: nameLastToken.charOffset));
4840+
invocationOffset: nameLastToken.charOffset,
4841+
inImplicitCreationContext: inImplicitCreationContext));
48404842
} else {
48414843
String? typeName;
48424844
if (type is ProblemBuilder) {
@@ -4863,8 +4865,9 @@ class BodyBuilder extends ScopeListener<JumpTarget>
48634865
String constructorName,
48644866
Arguments arguments,
48654867
{required int instantiationOffset,
4866-
required int invocationOffset}) {
4867-
if (enableConstructorTearOffsInLibrary) {
4868+
required int invocationOffset,
4869+
required bool inImplicitCreationContext}) {
4870+
if (enableConstructorTearOffsInLibrary && inImplicitCreationContext) {
48684871
Expression receiver = receiverFunction();
48694872
if (typeArguments != null) {
48704873
receiver = forest.createInstantiation(instantiationOffset, receiver,
@@ -4892,7 +4895,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
48924895
debugEvent("ImplicitCreationExpression");
48934896
_buildConstructorReferenceInvocation(
48944897
token.next!, token.offset, Constness.implicit,
4895-
inMetadata: false);
4898+
inMetadata: false, inImplicitCreationContext: true);
48964899
}
48974900

48984901
@override
@@ -5159,7 +5162,7 @@ class BodyBuilder extends ScopeListener<JumpTarget>
51595162
debugEvent("endConstExpression");
51605163
_buildConstructorReferenceInvocation(
51615164
token.next!, token.offset, Constness.explicitConst,
5162-
inMetadata: false);
5165+
inMetadata: false, inImplicitCreationContext: false);
51635166
}
51645167

51655168
@override

Diff for: pkg/front_end/lib/src/fasta/kernel/expression_generator.dart

+15-8
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,13 @@ abstract class Generator {
295295
Arguments arguments,
296296
Token nameToken,
297297
Token nameLastToken,
298-
Constness constness) {
298+
Constness constness,
299+
{required bool inImplicitCreationContext}) {
299300
return _helper.createInstantiationAndInvocation(() => buildSimpleRead(),
300301
typeArguments, _plainNameForRead, name, arguments,
301302
instantiationOffset: fileOffset,
302-
invocationOffset: nameLastToken.charOffset);
303+
invocationOffset: nameLastToken.charOffset,
304+
inImplicitCreationContext: inImplicitCreationContext);
303305
}
304306

305307
void printOn(StringSink sink);
@@ -2939,10 +2941,12 @@ class DeferredAccessGenerator extends Generator {
29392941
Arguments arguments,
29402942
Token nameToken,
29412943
Token nameLastToken,
2942-
Constness constness) {
2944+
Constness constness,
2945+
{required bool inImplicitCreationContext}) {
29432946
return _helper.wrapInDeferredCheck(
2944-
suffixGenerator.invokeConstructor(typeArguments, name, arguments,
2945-
nameToken, nameLastToken, constness),
2947+
suffixGenerator.invokeConstructor(
2948+
typeArguments, name, arguments, nameToken, nameLastToken, constness,
2949+
inImplicitCreationContext: inImplicitCreationContext),
29462950
prefixGenerator.prefix,
29472951
offsetForToken(suffixGenerator.token));
29482952
}
@@ -3055,7 +3059,8 @@ class TypeUseGenerator extends AbstractReadOnlyAccessGenerator {
30553059
Arguments arguments,
30563060
Token nameToken,
30573061
Token nameLastToken,
3058-
Constness constness) {
3062+
Constness constness,
3063+
{required bool inImplicitCreationContext}) {
30593064
return _helper.buildConstructorInvocation(
30603065
declaration,
30613066
nameToken,
@@ -3651,7 +3656,8 @@ abstract class ErroneousExpressionGenerator extends Generator {
36513656
Arguments arguments,
36523657
Token nameToken,
36533658
Token nameLastToken,
3654-
Constness constness) {
3659+
Constness constness,
3660+
{required bool inImplicitCreationContext}) {
36553661
if (typeArguments != null) {
36563662
assert(_forest.argumentsTypeArguments(arguments).isEmpty);
36573663
_forest.argumentsSetTypeArguments(
@@ -4280,7 +4286,8 @@ class ParserErrorGenerator extends Generator {
42804286
Arguments arguments,
42814287
Token nameToken,
42824288
Token nameLastToken,
4283-
Constness constness) {
4289+
Constness constness,
4290+
{required bool inImplicitCreationContext}) {
42844291
return buildProblem();
42854292
}
42864293

Diff for: pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart

+7-2
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ abstract class ExpressionGeneratorHelper implements InferenceHelper {
194194

195195
TypeEnvironment get typeEnvironment;
196196

197-
/// If explicit instantiations are support in this library, create an
197+
/// If explicit instantiations are supported in this library, create an
198198
/// instantiation of the result of [receiverFunction] using
199199
/// [typeArguments] followed by an invocation of [name] with [arguments].
200200
/// Otherwise create the errors for the corresponding invalid implicit
@@ -209,14 +209,19 @@ abstract class ExpressionGeneratorHelper implements InferenceHelper {
209209
/// class `b` with prefix `a` with type arguments `<c>`, but with explicit
210210
/// instantiation it could instead be the explicit instantiation of expression
211211
/// `a.b` with type arguments `<c>` followed by and invocation of `d()`.
212+
///
213+
/// If [inImplicitCreationContext] is `false`, then the expression is
214+
/// preceded by `new` or `const`, and an error should be reported instead of
215+
/// creating the instantiation and invocation.
212216
Expression createInstantiationAndInvocation(
213217
Expression Function() receiverFunction,
214218
List<UnresolvedType>? typeArguments,
215219
String className,
216220
String constructorName,
217221
Arguments arguments,
218222
{required int instantiationOffset,
219-
required int invocationOffset});
223+
required int invocationOffset,
224+
required bool inImplicitCreationContext});
220225
}
221226

222227
/// Checks that a generic [typedef] for a generic class.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) 2021, 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+
func() {}
6+
7+
@func()
8+
test() {
9+
const func();
10+
}
11+
12+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
6+
// @func()
7+
// ^^^^
8+
//
9+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:9:9: Error: Couldn't find constructor 'func'.
10+
// const func();
11+
// ^^^^
12+
//
13+
import self as self;
14+
15+
static method func() → dynamic {}
16+
@invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
17+
@func()
18+
^^^^"
19+
static method test() → dynamic {
20+
invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:9:9: Error: Couldn't find constructor 'func'.
21+
const func();
22+
^^^^";
23+
}
24+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
6+
// @func()
7+
// ^^^^
8+
//
9+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:9:9: Error: Couldn't find constructor 'func'.
10+
// const func();
11+
// ^^^^
12+
//
13+
import self as self;
14+
15+
static method func() → dynamic {}
16+
@invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
17+
@func()
18+
^^^^"
19+
static method test() → dynamic {
20+
invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:9:9: Error: Couldn't find constructor 'func'.
21+
const func();
22+
^^^^";
23+
}
24+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
func() {}
2+
@func()
3+
test() {}
4+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
func() {}
2+
main() {}
3+
@func()
4+
test() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
6+
// @func()
7+
// ^^^^
8+
//
9+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:9:9: Error: Couldn't find constructor 'func'.
10+
// const func();
11+
// ^^^^
12+
//
13+
import self as self;
14+
15+
static method func() → dynamic {}
16+
@invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
17+
@func()
18+
^^^^"
19+
static method test() → dynamic {
20+
invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:9:9: Error: Couldn't find constructor 'func'.
21+
const func();
22+
^^^^";
23+
}
24+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
6+
// @func()
7+
// ^^^^
8+
//
9+
import self as self;
10+
11+
static method func() → dynamic
12+
;
13+
@invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
14+
@func()
15+
^^^^"
16+
static method test() → dynamic
17+
;
18+
static method main() → dynamic
19+
;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
6+
// @func()
7+
// ^^^^
8+
//
9+
// pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:9:9: Error: Couldn't find constructor 'func'.
10+
// const func();
11+
// ^^^^
12+
//
13+
import self as self;
14+
15+
static method func() → dynamic {}
16+
@invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:7:2: Error: Couldn't find constructor 'func'.
17+
@func()
18+
^^^^"
19+
static method test() → dynamic {
20+
invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47069.dart:9:9: Error: Couldn't find constructor 'func'.
21+
const func();
22+
^^^^";
23+
}
24+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) 2021, 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+
dynamic a;
6+
7+
test() {
8+
new a();
9+
}
10+
11+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/constructor_tearoffs/issue47071.dart:8:7: Error: Couldn't find constructor 'a'.
6+
// new a();
7+
// ^
8+
//
9+
import self as self;
10+
11+
static field dynamic a;
12+
static method test() → dynamic {
13+
invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47071.dart:8:7: Error: Couldn't find constructor 'a'.
14+
new a();
15+
^";
16+
}
17+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/constructor_tearoffs/issue47071.dart:8:7: Error: Couldn't find constructor 'a'.
6+
// new a();
7+
// ^
8+
//
9+
import self as self;
10+
11+
static field dynamic a;
12+
static method test() → dynamic {
13+
invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47071.dart:8:7: Error: Couldn't find constructor 'a'.
14+
new a();
15+
^";
16+
}
17+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dynamic a;
2+
test() {}
3+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dynamic a;
2+
main() {}
3+
test() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/constructor_tearoffs/issue47071.dart:8:7: Error: Couldn't find constructor 'a'.
6+
// new a();
7+
// ^
8+
//
9+
import self as self;
10+
11+
static field dynamic a;
12+
static method test() → dynamic {
13+
invalid-expression "pkg/front_end/testcases/constructor_tearoffs/issue47071.dart:8:7: Error: Couldn't find constructor 'a'.
14+
new a();
15+
^";
16+
}
17+
static method main() → dynamic {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
library /*isNonNullableByDefault*/;
2+
import self as self;
3+
4+
static field dynamic a;
5+
static method test() → dynamic
6+
;
7+
static method main() → dynamic
8+
;

0 commit comments

Comments
 (0)