[dart2js] Test type directives

Change-Id: I4b0459bc097bb5618ab32f479a703ec35303436b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/109080
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
This commit is contained in:
Johnni Winther 2019-07-16 14:32:37 +00:00 committed by commit-bot@chromium.org
parent b2ed4b3c7b
commit 6d95cb72e2
11 changed files with 467 additions and 19 deletions

View file

@ -333,7 +333,9 @@ abstract class DeferredLoadTask extends CompilerTask {
_collectTypeDependencies(type, dependencies);
break;
case TypeUseKind.AS_CAST:
if (!closedWorld.annotationsData.omitAsCasts(element)) {
if (closedWorld.annotationsData
.getExplicitCastCheckPolicy(element)
.isEmitted) {
_collectTypeDependencies(type, dependencies);
}
break;

View file

@ -399,7 +399,7 @@ class ResolutionEnqueuer extends EnqueuerImpl {
_registerIsCheck(type);
break;
case TypeUseKind.AS_CAST:
if (!_annotationsData.omitAsCasts(member)) {
if (_annotationsData.getExplicitCastCheckPolicy(member).isEmitted) {
_registerIsCheck(type);
}
break;

View file

@ -351,10 +351,10 @@ abstract class AnnotationsData {
/// If [member] is `null`, the default policy is returned.
CheckPolicy getConditionCheckPolicy(MemberEntity member);
/// Whether to omit as casts.
/// Whether should the compiler do with explicit casts in [member].
///
/// If [member] is `null`, the default policy is returned.
bool omitAsCasts(MemberEntity member);
CheckPolicy getExplicitCastCheckPolicy(MemberEntity member);
}
class AnnotationsDataImpl implements AnnotationsData {
@ -365,7 +365,7 @@ class AnnotationsDataImpl implements AnnotationsData {
final CheckPolicy _defaultParameterCheckPolicy;
final CheckPolicy _defaultImplicitDowncastCheckPolicy;
final CheckPolicy _defaultConditionCheckPolicy;
final bool _defaultOmitAsCasts;
final CheckPolicy _defaultExplicitCastCheckPolicy;
final Map<MemberEntity, EnumSet<PragmaAnnotation>> pragmaAnnotations;
AnnotationsDataImpl(CompilerOptions options, this.pragmaAnnotations)
@ -373,7 +373,8 @@ class AnnotationsDataImpl implements AnnotationsData {
this._defaultImplicitDowncastCheckPolicy =
options.defaultImplicitDowncastCheckPolicy,
this._defaultConditionCheckPolicy = options.defaultConditionCheckPolicy,
this._defaultOmitAsCasts = options.defaultOmitAsCasts;
this._defaultExplicitCastCheckPolicy =
options.defaultExplicitCastCheckPolicy;
factory AnnotationsDataImpl.readFromDataSource(
CompilerOptions options, DataSource source) {
@ -526,18 +527,18 @@ class AnnotationsDataImpl implements AnnotationsData {
}
@override
bool omitAsCasts(MemberEntity member) {
CheckPolicy getExplicitCastCheckPolicy(MemberEntity member) {
if (member != null) {
EnumSet<PragmaAnnotation> annotations = pragmaAnnotations[member];
if (annotations != null) {
if (annotations.contains(PragmaAnnotation.asTrust)) {
return true;
return CheckPolicy.trusted;
} else if (annotations.contains(PragmaAnnotation.asCheck)) {
return false;
return CheckPolicy.checked;
}
}
}
return _defaultOmitAsCasts;
return _defaultExplicitCastCheckPolicy;
}
}

View file

@ -199,7 +199,7 @@ class CodegenEnqueuer extends EnqueuerImpl {
_registerIsCheck(type);
break;
case TypeUseKind.AS_CAST:
if (!_annotationsData.omitAsCasts(member)) {
if (_annotationsData.getExplicitCastCheckPolicy(member).isEmitted) {
_registerIsCheck(type);
}
break;

View file

@ -158,7 +158,9 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
onIsCheck(type, transformed);
break;
case TypeUseKind.AS_CAST:
if (!_annotationsData.omitAsCasts(worldImpact.member)) {
if (_annotationsData
.getExplicitCastCheckPolicy(worldImpact.member)
.isEmitted) {
onIsCheck(type, transformed);
hasAsCast = true;
}

View file

@ -256,7 +256,7 @@ class CompilerOptions implements DiagnosticOptions {
bool omitImplicitChecks = false;
/// Whether to omit as casts by default.
bool defaultOmitAsCasts = false;
bool omitAsCasts = false;
/// Whether to omit class type arguments only needed for `toString` on
/// `Object.runtimeType`.
@ -279,6 +279,11 @@ class CompilerOptions implements DiagnosticOptions {
/// This is an internal configuration option derived from other flags.
CheckPolicy defaultConditionCheckPolicy;
/// What should the compiler do with explicit casts.
///
/// This is an internal configuration option derived from other flags.
CheckPolicy defaultExplicitCastCheckPolicy;
/// Whether to generate code compliant with content security policy (CSP).
bool useContentSecurityPolicy = false;
@ -405,7 +410,7 @@ class CompilerOptions implements DiagnosticOptions {
platformBinaries ?? _extractUriOption(options, '--platform-binaries=')
..sourceMapUri = _extractUriOption(options, '--source-map=')
..omitImplicitChecks = _hasOption(options, Flags.omitImplicitChecks)
..defaultOmitAsCasts = _hasOption(options, Flags.omitAsCasts)
..omitAsCasts = _hasOption(options, Flags.omitAsCasts)
..laxRuntimeTypeToString =
_hasOption(options, Flags.laxRuntimeTypeToString)
..testMode = _hasOption(options, Flags.testMode)
@ -496,6 +501,11 @@ class CompilerOptions implements DiagnosticOptions {
defaultImplicitDowncastCheckPolicy = CheckPolicy.checked;
defaultConditionCheckPolicy = CheckPolicy.checked;
}
if (omitAsCasts) {
defaultExplicitCastCheckPolicy = CheckPolicy.trusted;
} else {
defaultExplicitCastCheckPolicy = CheckPolicy.checked;
}
if (_disableMinification) {
enableMinification = false;

View file

@ -2417,11 +2417,16 @@ class KernelSsaGraphBuilder extends ir.Visitor {
return;
}
if ((!node.isTypeError &&
!closedWorld.annotationsData.omitAsCasts(_currentFrame.member)) ||
closedWorld.annotationsData
.getImplicitDowncastCheckPolicy(_currentFrame.member)
.isEmitted) {
CheckPolicy policy;
if (node.isTypeError) {
policy = closedWorld.annotationsData
.getImplicitDowncastCheckPolicy(_currentFrame.member);
} else {
policy = closedWorld.annotationsData
.getExplicitCastCheckPolicy(_currentFrame.member);
}
if (policy.isEmitted) {
HInstruction converted = _typeBuilder.buildTypeConversion(
expressionInstruction,
localsHandler.substInContext(type),

View file

@ -0,0 +1,105 @@
// Copyright (c) 2019, 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.
main() {
var c = new Class();
c.method1a(null);
c.method1b(null);
c.method2a(null);
c.method2b(null);
c.method3a(null);
c.method3b(null);
c.method4a(null);
c.method4b(null);
c.method5a(null);
c.method5b(null);
c.method6a(null);
c.method6b(null);
}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class1a:explicit=[Class1a]*/
class Class1a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class1b:*/
class Class1b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class2a:explicit=[Class2a]*/
class Class2a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class2b:*/
class Class2b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class3a:explicit=[Class3a]*/
class Class3a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class3b:*/
class Class3b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class4a:explicit=[Class4a<int>],needsArgs*/
class Class4a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class4b:*/
class Class4b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class5a:explicit=[Class5a<int>],needsArgs*/
class Class5a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class5b:*/
class Class5b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class6a:explicit=[Class6a<int>],needsArgs*/
class Class6a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class6b:*/
class Class6b<T> {}
class Class {
@pragma('dart2js:parameter:check')
method1a(Class1a c) {}
@pragma('dart2js:parameter:trust')
method1b(Class1b c) {}
@pragma('dart2js:downcast:check')
Class2a method2a(o) => o;
@pragma('dart2js:downcast:trust')
Class2b method2b(o) => o;
@pragma('dart2js:as:check')
method3a(o) => o as Class3a;
@pragma('dart2js:as:trust')
method3b(o) => o as Class3b;
@pragma('dart2js:parameter:check')
method4a(Class4a<int> c) {}
@pragma('dart2js:parameter:trust')
method4b(Class4b<int> c) {}
@pragma('dart2js:downcast:check')
Class5a<int> method5a(o) => o;
@pragma('dart2js:downcast:trust')
Class5b<int> method5b(o) => o;
@pragma('dart2js:as:check')
method6a(o) => o as Class6a<int>;
@pragma('dart2js:as:trust')
method6b(o) => o as Class6b<int>;
}

View file

@ -0,0 +1,102 @@
// Copyright (c) 2019, 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.
main() {
method1a(null);
method1b(null);
method2a(null);
method2b(null);
method3a(null);
method3b(null);
method4a(null);
method4b(null);
method5a(null);
method5b(null);
method6a(null);
method6b(null);
}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class1a:explicit=[Class1a]*/
class Class1a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class1b:*/
class Class1b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class2a:explicit=[Class2a]*/
class Class2a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class2b:*/
class Class2b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class3a:explicit=[Class3a]*/
class Class3a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class3b:*/
class Class3b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class4a:explicit=[Class4a<int>],needsArgs*/
class Class4a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class4b:*/
class Class4b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class5a:explicit=[Class5a<int>],needsArgs*/
class Class5a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class5b:*/
class Class5b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class6a:explicit=[Class6a<int>],needsArgs*/
class Class6a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class6b:*/
class Class6b<T> {}
@pragma('dart2js:parameter:check')
method1a(Class1a c) {}
@pragma('dart2js:parameter:trust')
method1b(Class1b c) {}
@pragma('dart2js:downcast:check')
Class2a method2a(o) => o;
@pragma('dart2js:downcast:trust')
Class2b method2b(o) => o;
@pragma('dart2js:as:check')
method3a(o) => o as Class3a;
@pragma('dart2js:as:trust')
method3b(o) => o as Class3b;
@pragma('dart2js:parameter:check')
method4a(Class4a<int> c) {}
@pragma('dart2js:parameter:trust')
method4b(Class4b<int> c) {}
@pragma('dart2js:downcast:check')
Class5a<int> method5a(o) => o;
@pragma('dart2js:downcast:trust')
Class5b<int> method5b(o) => o;
@pragma('dart2js:as:check')
method6a(o) => o as Class6a<int>;
@pragma('dart2js:as:trust')
method6b(o) => o as Class6b<int>;

View file

@ -0,0 +1,110 @@
// Copyright (c) 2019, 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.
@pragma('dart2js:noInline')
@pragma('dart2js:assumeDynamic')
value(o) => o;
main() {
var c = new Class();
value(c).method1a(value(null));
value(c).method1b(value(null));
value(c).method2a(value(null));
value(c).method2b(value(null));
value(c).method3a(value(null));
value(c).method3b(value(null));
value(c).method4a(value(null));
value(c).method4b(value(null));
value(c).method5a(value(null));
value(c).method5b(value(null));
value(c).method6a(value(null));
value(c).method6b(value(null));
}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class1a:checkedInstance*/
class Class1a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class1b:*/
class Class1b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class2a:checkedInstance*/
class Class2a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class2b:*/
class Class2b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class3a:checkedInstance*/
class Class3a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class3b:*/
class Class3b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class4a:checkedInstance*/
class Class4a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class4b:*/
class Class4b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class5a:checkedInstance*/
class Class5a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class5b:*/
class Class5b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class6a:checkedInstance*/
class Class6a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class6b:*/
class Class6b<T> {}
/*class: Class:checks=[],instance*/
class Class {
@pragma('dart2js:parameter:check')
method1a(Class1a c) {}
@pragma('dart2js:parameter:trust')
method1b(Class1b c) {}
@pragma('dart2js:downcast:check')
Class2a method2a(o) => o;
@pragma('dart2js:downcast:trust')
Class2b method2b(o) => o;
@pragma('dart2js:as:check')
method3a(o) => o as Class3a;
@pragma('dart2js:as:trust')
method3b(o) => o as Class3b;
@pragma('dart2js:parameter:check')
method4a(Class4a<int> c) {}
@pragma('dart2js:parameter:trust')
method4b(Class4b<int> c) {}
@pragma('dart2js:downcast:check')
Class5a<int> method5a(o) => o;
@pragma('dart2js:downcast:trust')
Class5b<int> method5b(o) => o;
@pragma('dart2js:as:check')
method6a(o) => o as Class6a<int>;
@pragma('dart2js:as:trust')
method6b(o) => o as Class6b<int>;
}

View file

@ -0,0 +1,111 @@
// Copyright (c) 2019, 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.
@pragma('dart2js:noInline')
@pragma('dart2js:assumeDynamic')
value(o) => o;
main() {
method1a(value(null));
method1b(value(null));
method2a(value(null));
method2b(value(null));
method3a(value(null));
method3b(value(null));
method4a(value(null));
method4b(value(null));
method5a(value(null));
method5b(value(null));
method6a(value(null));
method6b(value(null));
}
// TODO(johnniwinther,sra): Find a way to check parameter checks on static
// methods. For [Class1a], [Class1b], [Class4a] and [Class4b] either the CFE
// inserts an implicit cast at the call-site or we disregard the forced check
// because it is a static call.
/*strong.class: Class1a:checkedInstance*/
/*omit.class: Class1a:*/
class Class1a {}
/*strong.class: Class1b:checkedInstance*/
/*omit.class: Class1b:*/
class Class1b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class2a:checkedInstance*/
class Class2a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class2b:*/
class Class2b {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class3a:checkedInstance*/
class Class3a {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class3b:*/
class Class3b {}
/*strong.class: Class4a:checkedInstance*/
/*omit.class: Class4a:*/
class Class4a<T> {}
/*strong.class: Class4b:checkedInstance*/
/*omit.class: Class4b:*/
class Class4b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class5a:checkedInstance*/
class Class5a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class5b:*/
class Class5b<T> {}
// Checks are needed both with and without --omit-implicit-checks.
/*class: Class6a:checkedInstance*/
class Class6a<T> {}
// Checks are needed neither with nor without --omit-implicit-checks.
/*class: Class6b:*/
class Class6b<T> {}
@pragma('dart2js:parameter:check')
method1a(Class1a c) {}
@pragma('dart2js:parameter:trust')
method1b(Class1b c) {}
@pragma('dart2js:downcast:check')
Class2a method2a(o) => o;
@pragma('dart2js:downcast:trust')
Class2b method2b(o) => o;
@pragma('dart2js:as:check')
method3a(o) => o as Class3a;
@pragma('dart2js:as:trust')
method3b(o) => o as Class3b;
@pragma('dart2js:parameter:check')
method4a(Class4a<int> c) {}
@pragma('dart2js:parameter:trust')
method4b(Class4b<int> c) {}
@pragma('dart2js:downcast:check')
Class5a<int> method5a(o) => o;
@pragma('dart2js:downcast:trust')
Class5b<int> method5b(o) => o;
@pragma('dart2js:as:check')
method6a(o) => o as Class6a<int>;
@pragma('dart2js:as:trust')
method6b(o) => o as Class6b<int>;