mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
Make initializing formal access available by default
This CL changes dart2js such that the effect that we used to get with option '--initializing-formal-access' is now obtained unconditionally, i.e., that extension is now enabled by default. dart2js will continue to accept the option, such that scripts passing the option will not break. The CL is _not_ intended to be landed at this time, the plan is to enable the feature in a coordinated manner when all tools are ready. R=johnniwinther@google.com Review URL: https://codereview.chromium.org/2141023002 .
This commit is contained in:
parent
843bb96813
commit
4912fd1501
|
@ -74,9 +74,12 @@ class Flags {
|
|||
// https://gist.github.com/eernstg/4353d7b4f669745bed3a5423e04a453c.
|
||||
static const String genericMethodSyntax = '--generic-method-syntax';
|
||||
|
||||
// Initializing-formal access is enabled by default and cannot be disabled.
|
||||
// For backward compatibility the option is still accepted, but it is ignored.
|
||||
static const String initializingFormalAccess = '--initializing-formal-access';
|
||||
|
||||
// Experimental flags.
|
||||
static const String resolveOnly = '--resolve-only';
|
||||
static const String initializingFormalAccess = '--initializing-formal-access';
|
||||
}
|
||||
|
||||
class Option {
|
||||
|
|
|
@ -1241,13 +1241,10 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
|||
if (parameter.isInitializingFormal) {
|
||||
InitializingFormalElement initializingFormal = parameter;
|
||||
updateFieldValue(node, initializingFormal.fieldElement, argument);
|
||||
if (compiler.options.enableInitializingFormalAccess) {
|
||||
definitions[parameter] = argument;
|
||||
}
|
||||
} else {
|
||||
potentiallyCheckType(parameter, argument);
|
||||
definitions[parameter] = argument;
|
||||
}
|
||||
definitions[parameter] = argument;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -335,7 +335,7 @@ Future<api.CompilationResult> compile(List<String> argv) {
|
|||
new OptionHandler(Flags.allowMockCompilation, passThrough),
|
||||
new OptionHandler(Flags.fastStartup, passThrough),
|
||||
new OptionHandler(Flags.genericMethodSyntax, ignoreOption),
|
||||
new OptionHandler(Flags.initializingFormalAccess, passThrough),
|
||||
new OptionHandler(Flags.initializingFormalAccess, ignoreOption),
|
||||
new OptionHandler('${Flags.minify}|-m', implyCompilation),
|
||||
new OptionHandler(Flags.preserveUris, passThrough),
|
||||
new OptionHandler('--force-strip=.*', setStrip),
|
||||
|
|
|
@ -133,10 +133,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
/// reason for why an assertion fails. (experimental)
|
||||
final bool enableAssertMessage;
|
||||
|
||||
/// Support access to initializing formal constructor arguments, e.g., the
|
||||
/// use of `x` to initialize `y` in `C(this.x) : y = x`.
|
||||
final bool enableInitializingFormalAccess;
|
||||
|
||||
/// Whether the user specified a flag to allow the use of dart:mirrors. This
|
||||
/// silences a warning produced by the compiler.
|
||||
final bool enableExperimentalMirrors;
|
||||
|
@ -272,8 +268,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
disableTypeInference: _hasOption(options, Flags.disableTypeInference),
|
||||
dumpInfo: _hasOption(options, Flags.dumpInfo),
|
||||
enableAssertMessage: _hasOption(options, Flags.enableAssertMessage),
|
||||
enableInitializingFormalAccess:
|
||||
_hasOption(options, Flags.initializingFormalAccess),
|
||||
enableExperimentalMirrors:
|
||||
_hasOption(options, Flags.enableExperimentalMirrors),
|
||||
enableMinification: _hasOption(options, Flags.minify),
|
||||
|
@ -340,7 +334,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
bool disableTypeInference: false,
|
||||
bool dumpInfo: false,
|
||||
bool enableAssertMessage: false,
|
||||
bool enableInitializingFormalAccess: false,
|
||||
bool enableExperimentalMirrors: false,
|
||||
bool enableMinification: false,
|
||||
bool enableNativeLiveTypeAnalysis: true,
|
||||
|
@ -411,7 +404,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
disableTypeInference: disableTypeInference,
|
||||
dumpInfo: dumpInfo,
|
||||
enableAssertMessage: enableAssertMessage,
|
||||
enableInitializingFormalAccess: enableInitializingFormalAccess,
|
||||
enableExperimentalMirrors: enableExperimentalMirrors,
|
||||
enableMinification: enableMinification,
|
||||
enableNativeLiveTypeAnalysis: enableNativeLiveTypeAnalysis,
|
||||
|
@ -461,7 +453,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
this.disableTypeInference: false,
|
||||
this.dumpInfo: false,
|
||||
this.enableAssertMessage: false,
|
||||
this.enableInitializingFormalAccess: false,
|
||||
this.enableExperimentalMirrors: false,
|
||||
this.enableMinification: false,
|
||||
this.enableNativeLiveTypeAnalysis: false,
|
||||
|
@ -518,7 +509,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
disableTypeInference,
|
||||
dumpInfo,
|
||||
enableAssertMessage,
|
||||
enableInitializingFormalAccess,
|
||||
enableExperimentalMirrors,
|
||||
enableMinification,
|
||||
enableNativeLiveTypeAnalysis,
|
||||
|
@ -576,8 +566,6 @@ class CompilerOptions implements DiagnosticOptions {
|
|||
disableTypeInference ?? options.disableTypeInference,
|
||||
dumpInfo: dumpInfo ?? options.dumpInfo,
|
||||
enableAssertMessage: enableAssertMessage ?? options.enableAssertMessage,
|
||||
enableInitializingFormalAccess: enableInitializingFormalAccess ??
|
||||
options.enableInitializingFormalAccess,
|
||||
enableExperimentalMirrors:
|
||||
enableExperimentalMirrors ?? options.enableExperimentalMirrors,
|
||||
enableMinification: enableMinification ?? options.enableMinification,
|
||||
|
|
|
@ -294,8 +294,7 @@ class InitializerResolver {
|
|||
* Resolve all initializers of this constructor. In the case of a redirecting
|
||||
* constructor, the resolved constructor's function element is returned.
|
||||
*/
|
||||
ConstructorElement resolveInitializers(
|
||||
{bool enableInitializingFormalAccess: false}) {
|
||||
ConstructorElement resolveInitializers() {
|
||||
Map<dynamic /*String|int*/, ConstantExpression> defaultValues =
|
||||
<dynamic /*String|int*/, ConstantExpression>{};
|
||||
ConstructedConstantExpression constructorInvocation;
|
||||
|
@ -303,12 +302,10 @@ class InitializerResolver {
|
|||
// that we can ensure that fields are initialized only once.
|
||||
FunctionSignature functionParameters = constructor.functionSignature;
|
||||
Scope oldScope = visitor.scope;
|
||||
if (enableInitializingFormalAccess) {
|
||||
// In order to get the correct detection of name clashes between all
|
||||
// parameters (regular ones and initializing formals) we must extend
|
||||
// the parameter scope rather than adding a new nested scope.
|
||||
visitor.scope = new ExtensionScope(visitor.scope);
|
||||
}
|
||||
// In order to get the correct detection of name clashes between all
|
||||
// parameters (regular ones and initializing formals) we must extend
|
||||
// the parameter scope rather than adding a new nested scope.
|
||||
visitor.scope = new ExtensionScope(visitor.scope);
|
||||
Link<Node> parameterNodes = (functionNode.parameters == null)
|
||||
? const Link<Node>()
|
||||
: functionNode.parameters.nodes;
|
||||
|
@ -349,10 +346,8 @@ class InitializerResolver {
|
|||
registry.registerStaticUse(new StaticUse.fieldInit(field));
|
||||
}
|
||||
checkForDuplicateInitializers(field, element.initializer);
|
||||
if (enableInitializingFormalAccess) {
|
||||
visitor.defineLocalVariable(parameterNode, initializingFormal);
|
||||
visitor.addToScope(initializingFormal);
|
||||
}
|
||||
visitor.defineLocalVariable(parameterNode, initializingFormal);
|
||||
visitor.addToScope(initializingFormal);
|
||||
if (isConst) {
|
||||
if (element.isNamed) {
|
||||
fieldInitializers[field] = new NamedArgumentReference(element.name);
|
||||
|
|
|
@ -2573,8 +2573,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
} else {
|
||||
semantics = new StaticAccess.parameter(element);
|
||||
}
|
||||
} else if (element.isInitializingFormal &&
|
||||
options.enableInitializingFormalAccess) {
|
||||
} else if (element.isInitializingFormal) {
|
||||
error = reportAndCreateErroneousElement(node.selector, name.text,
|
||||
MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name});
|
||||
semantics = new StaticAccess.finalParameter(element);
|
||||
|
|
|
@ -247,9 +247,7 @@ class ResolverTask extends CompilerTask {
|
|||
// resolution in case there is an implicit super constructor call.
|
||||
InitializerResolver resolver =
|
||||
new InitializerResolver(visitor, element, tree);
|
||||
FunctionElement redirection = resolver.resolveInitializers(
|
||||
enableInitializingFormalAccess:
|
||||
options.enableInitializingFormalAccess);
|
||||
FunctionElement redirection = resolver.resolveInitializers();
|
||||
if (redirection != null) {
|
||||
resolveRedirectingConstructor(resolver, tree, element, redirection);
|
||||
}
|
||||
|
|
|
@ -686,11 +686,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|||
message: 'Missing element for identifier'));
|
||||
assert(invariant(
|
||||
node,
|
||||
element.isVariable ||
|
||||
element.isRegularParameter ||
|
||||
element.isField ||
|
||||
(element.isInitializingFormal &&
|
||||
compiler.options.enableInitializingFormalAccess),
|
||||
element.isVariable || element.isParameter || element.isField,
|
||||
message: 'Unexpected context element ${element}'));
|
||||
return element.computeType(resolution);
|
||||
}
|
||||
|
@ -775,10 +771,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|||
return access;
|
||||
}
|
||||
if (receiverElement != null &&
|
||||
(receiverElement.isVariable ||
|
||||
receiverElement.isRegularParameter ||
|
||||
(receiverElement.isInitializingFormal &&
|
||||
compiler.options.enableInitializingFormalAccess))) {
|
||||
(receiverElement.isVariable || receiverElement.isParameter)) {
|
||||
Link<TypePromotion> typePromotions = typePromotionsMap[receiverElement];
|
||||
if (typePromotions != null) {
|
||||
while (!typePromotions.isEmpty) {
|
||||
|
@ -1095,10 +1088,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|||
}
|
||||
|
||||
ElementAccess createPromotedAccess(Element element) {
|
||||
if (element.isVariable ||
|
||||
element.isRegularParameter ||
|
||||
(element.isInitializingFormal &&
|
||||
compiler.options.enableInitializingFormalAccess)) {
|
||||
if (element.isVariable || element.isParameter) {
|
||||
TypePromotion typePromotion = getKnownTypePromotion(element);
|
||||
if (typePromotion != null) {
|
||||
return new PromotedAccess(element, typePromotion.type);
|
||||
|
@ -1215,11 +1205,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|||
}
|
||||
}
|
||||
|
||||
if (variable != null &&
|
||||
(variable.isVariable ||
|
||||
variable.isRegularParameter ||
|
||||
(variable.isInitializingFormal &&
|
||||
compiler.options.enableInitializingFormalAccess))) {
|
||||
if (variable != null && (variable.isVariable || variable.isParameter)) {
|
||||
DartType knownType = getKnownType(variable);
|
||||
if (!knownType.isDynamic) {
|
||||
DartType shownType = elements.getType(node.arguments.head);
|
||||
|
|
|
@ -14,7 +14,7 @@ class TestClass {
|
|||
TestClass.named(num this.fld1)
|
||||
// Should cause a compilation error (for the spawned isolate). It is a
|
||||
// runtime error for the test.
|
||||
: fld2 = fld1 /// 01: compile-time error
|
||||
: fld2 = this.fld1 /// 01: compile-time error
|
||||
;
|
||||
num fld1;
|
||||
num fld2;
|
||||
|
|
|
@ -8,9 +8,14 @@
|
|||
import "package:expect/expect.dart";
|
||||
|
||||
class A {
|
||||
int x;
|
||||
String y;
|
||||
A(this.x) : y = x { y = x; }
|
||||
num x;
|
||||
double y;
|
||||
// Finding the type of an initializing formal: should cause a warning
|
||||
// in the initializer but not the body, because the former has type
|
||||
// `int` and the latter has type `num`.
|
||||
A(int this.x) : y = x {
|
||||
y = x;
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
|
|
|
@ -106,7 +106,7 @@ initializing_formal_access_test: Skip
|
|||
initializing_formal_capture_test: Skip
|
||||
initializing_formal_final_test: Skip
|
||||
initializing_formal_type_test: Skip
|
||||
initializing_formal_promotion_test: Skip
|
||||
parameter_initializer5_test: Skip
|
||||
|
||||
# Experimental feature: Syntactic support for generic methods.
|
||||
# Skip these in dartium, because the test framework can't pass VM flags to
|
||||
|
|
|
@ -356,7 +356,6 @@ parameter_initializer1_negative_test: CompileTimeError
|
|||
parameter_initializer2_negative_test: CompileTimeError
|
||||
parameter_initializer3_negative_test: CompileTimeError
|
||||
parameter_initializer4_negative_test: CompileTimeError
|
||||
parameter_initializer5_negative_test: CompileTimeError
|
||||
parameter_initializer6_negative_test: CompileTimeError
|
||||
parser_quirks_test: StaticWarning
|
||||
part2_test: StaticWarning
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
// Copyright (c) 2011, 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.
|
||||
//
|
||||
// DartOptions=--initializing-formal-access
|
||||
// VMOptions=--initializing-formal-access
|
||||
|
||||
// Fails because this.x parameter is used in initializer expression.
|
||||
// Use the this.x parameter in an initializer expression.
|
||||
|
||||
class Foo {
|
||||
var x, y;
|
||||
Foo(this.x): y = x { }
|
||||
}
|
||||
|
||||
|
||||
main() {
|
||||
new Foo(12);
|
||||
}
|
Loading…
Reference in a new issue