| Index: pkg/compiler/lib/src/resolution/constructors.dart
|
| diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
|
| index 7a4dbc68af735d296d314058213cbcc0a99162b1..e30cfdcd7e496a70befa528d5db98275db08b9fc 100644
|
| --- a/pkg/compiler/lib/src/resolution/constructors.dart
|
| +++ b/pkg/compiler/lib/src/resolution/constructors.dart
|
| @@ -32,6 +32,7 @@ import 'members.dart' show lookupInScope, ResolverVisitor;
|
| import 'registry.dart' show ResolutionRegistry;
|
| import 'resolution_common.dart' show CommonResolverVisitor;
|
| import 'resolution_result.dart';
|
| +import 'scope.dart' show Scope, ExtensionScope;
|
|
|
| class InitializerResolver {
|
| final ResolverVisitor visitor;
|
| @@ -294,14 +295,30 @@ 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() {
|
| + ConstructorElement resolveInitializers(
|
| + {bool enableInitializingFormalAccess: false}) {
|
| Map<dynamic /*String|int*/, ConstantExpression> defaultValues =
|
| <dynamic /*String|int*/, ConstantExpression>{};
|
| ConstructedConstantExpression constructorInvocation;
|
| // Keep track of all "this.param" parameters specified for constructor so
|
| // 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);
|
| + }
|
| + Link<Node> parameterNodes = (functionNode.parameters == null)
|
| + ? const Link<Node>()
|
| + : functionNode.parameters.nodes;
|
| functionParameters.forEachParameter((ParameterElementX element) {
|
| + List<Element> optionals = functionParameters.optionalParameters;
|
| + if (!optionals.isEmpty && element == optionals.first) {
|
| + NodeList nodes = parameterNodes.head;
|
| + parameterNodes = nodes.nodes;
|
| + }
|
| if (isConst) {
|
| if (element.isOptional) {
|
| if (element.constantCache == null) {
|
| @@ -325,9 +342,15 @@ class InitializerResolver {
|
| }
|
| }
|
| if (element.isInitializingFormal) {
|
| + VariableDefinitions variableDefinitions = parameterNodes.head;
|
| + Node parameterNode = variableDefinitions.definitions.nodes.head;
|
| InitializingFormalElementX initializingFormal = element;
|
| FieldElement field = initializingFormal.fieldElement;
|
| checkForDuplicateInitializers(field, element.initializer);
|
| + if (enableInitializingFormalAccess) {
|
| + visitor.defineLocalVariable(parameterNode, initializingFormal);
|
| + visitor.addToScope(initializingFormal);
|
| + }
|
| if (isConst) {
|
| if (element.isNamed) {
|
| fieldInitializers[field] = new NamedArgumentReference(element.name);
|
| @@ -339,6 +362,7 @@ class InitializerResolver {
|
| isValidAsConstant = false;
|
| }
|
| }
|
| + parameterNodes = parameterNodes.tail;
|
| });
|
|
|
| if (functionNode.initializers == null) {
|
| @@ -430,6 +454,7 @@ class InitializerResolver {
|
| fieldInitializers,
|
| constructorInvocation);
|
| }
|
| + visitor.scope = oldScope;
|
| return null; // If there was no redirection always return null.
|
| }
|
| }
|
|
|