blob: 94b624c5f69a81ca9bfac1cf44cf3c5a2d7ee004 [file] [log] [blame]
// Copyright (c) 2021, 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.
// test w/ `dart test test/rule_test.dart -N avoid_dynamic_calls`
import 'dart:core';
import 'dart:core' as core_top_level_prefix_as;
void explicitDynamicType(dynamic object) {
object.foo(); // LINT
object.bar; // LINT
}
void implicitDynamicType(object) {
object.foo(); // LINT
object.bar; // LINT
}
// This would likely not pass at runtime, but we're using it for inference only.
T genericType<T>() => null as T;
void inferredDynamicType() {
var object = genericType();
object.foo(); // LINT
object.bar; // LINT
}
class Wrapper<T> {
final T field;
Wrapper(this.field);
}
void fieldDynamicType(Wrapper<dynamic> wrapper) {
wrapper.field.foo(); // LINT
wrapper.field.bar; // LINT
wrapper.field(); // LINT
(wrapper.field)(); // LINT
}
void cascadeExpressions(dynamic a, Wrapper<dynamic> b) {
a..b; // LINT
b..field; // OK
b
..toString
..field.a() // LINT
..field.b; // LINT
}
class TearOffFunction {
static int staticDoThing() => 0;
int doThing() => 0;
}
void otherPropertyAccessOrCalls(dynamic a) {
a(); // LINT
a?.b; // LINT
a!.b; // LINT
a?.b(); // LINT
a!.b(); // LINT
(a).b; // LINT
}
void tearOffFunctions(TearOffFunction a) {
var p = core_top_level_prefix_as.print; // OK
core_top_level_prefix_as.print('Hello'); // OK
p('Hello'); // OK
var doThing = a.doThing; // OK
doThing(); // OK
var staticDoThing = TearOffFunction.staticDoThing; // OK
staticDoThing(); // OK
identical(true, false); // OK
var alsoIdentical = identical;
alsoIdentical(true, false); // OK
}
typedef F = void Function();
void functionExpressionInvocations(
dynamic a(),
Function b(),
void Function() c,
d(),
F f,
F? fn,
) {
a(); // OK
a()(); // LINT
b(); // OK
b()(); // LINT
c(); // OK
d(); // OK
f.call; // OK
f.call(); // OK
fn?.call; // OK
fn?.call(); // OK
}
void typedFunctionButBasicallyDynamic(Function a, Wrapper<Function> b) {
a(); // LINT
b.field(); // LINT
(b.field)(); // LINT
a.call; // OK
a.call(); // LINT
}
void binaryExpressions(dynamic a, int b, bool c) {
a + a; // LINT
a + b; // LINT
a > b; // LINT
a < b; // LINT
a >= b; // LINT
a <= b; // LINT
a ^ b; // LINT
a | b; // LINT
a & b; // LINT
a % b; // LINT
a / b; // LINT
a ~/ b; // LINT
a >> b; // LINT
a << b; // LINT
a || c; // OK; this is an implicit downcast, not a dynamic call
a && c; // OK; this is an implicit downcast, not a dynamic call
b + a; // OK; this is an implicit downcast, not a dynamic call
a ?? b; // OK; this is a null comparison, not a dynamic call.
a is int; // OK
a is! int; // OK
a as int; // OK
}
void equalityExpressions(dynamic a, dynamic b) {
a == b; // OK, see lint description for details.
a == null; // OK.
a != b; // OK
a != null; // OK.
}
void membersThatExistOnObject(dynamic a, Invocation b) {
a.hashCode; // OK
a.runtimeType; // OK
a.noSuchMethod(); // LINT
a.noSuchMethod(b); // OK
a.noSuchMethod(b, 1); // LINT
a.noSuchMethod(b, name: 1); // LINT
a.toString(); // OK
a.toString(1); // LINT
a.toString(name: 1); // LINT
'$a'; // OK
'${a}'; // OK
}
void memberTearOffsOnObject(dynamic a, Invocation b) {
var tearOffNoSuchMethod = a.noSuchMethod; // OK
tearOffNoSuchMethod(b); // OK
var tearOffToString = a.toString; // OK
tearOffToString(); // OK
}
void assignmentExpressions(dynamic a) {
a += 1; // LINT
a -= 1; // LINT
a *= 1; // LINT
a ^= 1; // LINT
a /= 1; // LINT
a &= 1; // LINT
a |= 1; // LINT
a ??= 1; // OK
}
void prefixExpressions(dynamic a, int b) {
!a; // LINT
-a; // LINT
++a; // LINT
--a; // LINT
++b; // OK
--b; // OK
}
void postfixExpressions(dynamic a, int b) {
a!; // OK; this is not a dynamic call.
a++; // LINT
a--; // LINT
b++; // OK
b--; // OK
}
void indexExpressions(dynamic a) {
a[1]; // LINT
a[1] = 1; // LINT
a = a[1]; // LINT
}