OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/names.dart' show Selectors; | 8 import '../common/names.dart' show Selectors; |
9 import '../common/resolution.dart' show Feature; | 9 import '../common/resolution.dart' show Feature; |
10 import '../compiler.dart' show Compiler; | 10 import '../compiler.dart' show Compiler; |
11 import '../constants/constructors.dart' | 11 import '../constants/constructors.dart' |
12 show RedirectingFactoryConstantConstructor; | 12 show RedirectingFactoryConstantConstructor; |
13 import '../constants/expressions.dart'; | 13 import '../constants/expressions.dart'; |
14 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
15 import '../core_types.dart'; | 15 import '../core_types.dart'; |
16 import '../dart_types.dart'; | 16 import '../dart_types.dart'; |
17 import '../elements/elements.dart'; | 17 import '../elements/elements.dart'; |
18 import '../elements/modelx.dart' | 18 import '../elements/modelx.dart' |
19 show | 19 show |
20 BaseFunctionElementX, | |
20 ConstructorElementX, | 21 ConstructorElementX, |
21 ErroneousElementX, | 22 ErroneousElementX, |
22 FunctionElementX, | 23 FunctionElementX, |
23 JumpTargetX, | 24 JumpTargetX, |
24 LocalFunctionElementX, | 25 LocalFunctionElementX, |
25 LocalParameterElementX, | 26 LocalParameterElementX, |
26 MethodElementX, | 27 MethodElementX, |
27 ParameterElementX, | 28 ParameterElementX, |
28 VariableElementX, | 29 VariableElementX, |
29 VariableList; | 30 VariableList; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 r'>|' | 137 r'>|' |
137 r'<=|' | 138 r'<=|' |
138 r'<|' | 139 r'<|' |
139 r'&|' | 140 r'&|' |
140 r'\^|' | 141 r'\^|' |
141 r'\|' | 142 r'\|' |
142 r')$'); | 143 r')$'); |
143 | 144 |
144 ResolverVisitor( | 145 ResolverVisitor( |
145 Compiler compiler, Element element, ResolutionRegistry registry, | 146 Compiler compiler, Element element, ResolutionRegistry registry, |
146 {bool useEnclosingScope: false}) | 147 {Scope scope, bool useEnclosingScope: false}) |
147 : this.enclosingElement = element, | 148 : this.enclosingElement = element, |
148 // When the element is a field, we are actually resolving its | 149 // When the element is a field, we are actually resolving its |
149 // initial value, which should not have access to instance | 150 // initial value, which should not have access to instance |
150 // fields. | 151 // fields. |
151 inInstanceContext = (element.isInstanceMember && !element.isField) || | 152 inInstanceContext = (element.isInstanceMember && !element.isField) || |
152 element.isGenerativeConstructor, | 153 element.isGenerativeConstructor, |
153 this.currentClass = | 154 this.currentClass = |
154 element.isClassMember ? element.enclosingClass : null, | 155 element.isClassMember ? element.enclosingClass : null, |
155 this.statementScope = new StatementScope(), | 156 this.statementScope = new StatementScope(), |
156 scope = useEnclosingScope | 157 this.scope = scope ?? (useEnclosingScope |
157 ? Scope.buildEnclosingScope(element) | 158 ? Scope.buildEnclosingScope(element) |
158 : element.buildScope(), | 159 : element.buildScope()), |
159 // The type annotations on a typedef do not imply type checks. | 160 // The type annotations on a typedef do not imply type checks. |
160 // TODO(karlklose): clean this up (dartbug.com/8870). | 161 // TODO(karlklose): clean this up (dartbug.com/8870). |
161 inCheckContext = compiler.options.enableTypeAssertions && | 162 inCheckContext = compiler.options.enableTypeAssertions && |
162 !element.isLibrary && | 163 !element.isLibrary && |
163 !element.isTypedef && | 164 !element.isTypedef && |
164 !element.enclosingElement.isTypedef, | 165 !element.enclosingElement.isTypedef, |
165 inCatchBlock = false, | 166 inCatchBlock = false, |
166 constantState = element.isConst | 167 constantState = element.isConst |
167 ? ConstantState.CONSTANT | 168 ? ConstantState.CONSTANT |
168 : ConstantState.NON_CONSTANT, | 169 : ConstantState.NON_CONSTANT, |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
401 return classElement.lookupConstructor(name.text); | 402 return classElement.lookupConstructor(name.text); |
402 } | 403 } |
403 return null; | 404 return null; |
404 } | 405 } |
405 | 406 |
406 void setupFunction(FunctionExpression node, FunctionElement function) { | 407 void setupFunction(FunctionExpression node, FunctionElement function) { |
407 Element enclosingElement = function.enclosingElement; | 408 Element enclosingElement = function.enclosingElement; |
408 if (node.modifiers.isStatic && enclosingElement.kind != ElementKind.CLASS) { | 409 if (node.modifiers.isStatic && enclosingElement.kind != ElementKind.CLASS) { |
409 reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); | 410 reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); |
410 } | 411 } |
412 FunctionSignature functionSignature = function.functionSignature; | |
411 | 413 |
414 // Create the scope where the type variables are introduced, if any. | |
412 scope = new MethodScope(scope, function); | 415 scope = new MethodScope(scope, function); |
413 // Put the parameters in scope. | 416 functionSignature.typeVariables.forEach( |
414 FunctionSignature functionParameters = function.functionSignature; | 417 (DartType type) => addToScope(type.element)); |
418 | |
419 // Create the scope for the function body, and put the parameters in scope. | |
420 scope = new BlockScope(scope); | |
415 Link<Node> parameterNodes = | 421 Link<Node> parameterNodes = |
416 (node.parameters == null) ? const Link<Node>() : node.parameters.nodes; | 422 (node.parameters == null) ? const Link<Node>() : node.parameters.nodes; |
417 functionParameters.forEachParameter((ParameterElementX element) { | 423 functionSignature.forEachParameter((ParameterElementX element) { |
418 // TODO(karlklose): should be a list of [FormalElement]s, but the actual | 424 // TODO(karlklose): should be a list of [FormalElement]s, but the actual |
419 // implementation uses [Element]. | 425 // implementation uses [Element]. |
420 List<Element> optionals = functionParameters.optionalParameters; | 426 List<Element> optionals = functionSignature.optionalParameters; |
421 if (!optionals.isEmpty && element == optionals.first) { | 427 if (!optionals.isEmpty && element == optionals.first) { |
422 NodeList nodes = parameterNodes.head; | 428 NodeList nodes = parameterNodes.head; |
423 parameterNodes = nodes.nodes; | 429 parameterNodes = nodes.nodes; |
424 } | 430 } |
425 if (element.isOptional) { | 431 if (element.isOptional) { |
426 if (element.initializer != null) { | 432 if (element.initializer != null) { |
427 ResolutionResult result = visitInConstantContext(element.initializer); | 433 ResolutionResult result = visitInConstantContext(element.initializer); |
428 if (result.isConstant) { | 434 if (result.isConstant) { |
429 element.constant = result.constant; | 435 element.constant = result.constant; |
430 } | 436 } |
431 } else { | 437 } else { |
432 element.constant = new NullConstantExpression(); | 438 element.constant = new NullConstantExpression(); |
433 } | 439 } |
434 } | 440 } |
435 VariableDefinitions variableDefinitions = parameterNodes.head; | 441 VariableDefinitions variableDefinitions = parameterNodes.head; |
436 Node parameterNode = variableDefinitions.definitions.nodes.head; | 442 Node parameterNode = variableDefinitions.definitions.nodes.head; |
437 // Field parameters (this.x) are not visible inside the constructor. The | 443 // Field parameters (this.x) are not visible inside the constructor. The |
438 // fields they reference are visible, but must be resolved independently. | 444 // fields they reference are visible, but must be resolved independently. |
439 if (element.isInitializingFormal) { | 445 if (element.isInitializingFormal) { |
440 registry.useElement(parameterNode, element); | 446 registry.useElement(parameterNode, element); |
441 } else { | 447 } else { |
442 LocalParameterElementX parameterElement = element; | 448 LocalParameterElementX parameterElement = element; |
443 defineLocalVariable(parameterNode, parameterElement); | 449 defineLocalVariable(parameterNode, parameterElement); |
444 addToScope(parameterElement); | 450 addToScope(parameterElement); |
445 } | 451 } |
446 parameterNodes = parameterNodes.tail; | 452 parameterNodes = parameterNodes.tail; |
447 }); | 453 }); |
448 addDeferredAction(enclosingElement, () { | 454 addDeferredAction(enclosingElement, () { |
449 functionParameters | 455 functionSignature |
450 .forEachOptionalParameter((ParameterElementX parameter) { | 456 .forEachOptionalParameter((ParameterElementX parameter) { |
451 parameter.constant = | 457 parameter.constant = |
452 compiler.resolver.constantCompiler.compileConstant(parameter); | 458 compiler.resolver.constantCompiler.compileConstant(parameter); |
453 }); | 459 }); |
454 }); | 460 }); |
455 if (inCheckContext) { | 461 if (inCheckContext) { |
456 functionParameters.forEachParameter((ParameterElement element) { | 462 functionSignature.forEachParameter((ParameterElement element) { |
457 registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type)); | 463 registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type)); |
458 }); | 464 }); |
459 } | 465 } |
460 } | 466 } |
461 | 467 |
462 ResolutionResult visitAssert(Assert node) { | 468 ResolutionResult visitAssert(Assert node) { |
463 if (!compiler.options.enableAssertMessage) { | 469 if (!compiler.options.enableAssertMessage) { |
464 if (node.hasMessage) { | 470 if (node.hasMessage) { |
465 reporter.reportErrorMessage( | 471 reporter.reportErrorMessage( |
466 node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE); | 472 node, MessageKind.EXPERIMENTAL_ASSERT_MESSAGE); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
563 String name; | 569 String name; |
564 if (node.name == null) { | 570 if (node.name == null) { |
565 name = ""; | 571 name = ""; |
566 } else { | 572 } else { |
567 name = node.name.asIdentifier().source; | 573 name = node.name.asIdentifier().source; |
568 } | 574 } |
569 LocalFunctionElementX function = new LocalFunctionElementX( | 575 LocalFunctionElementX function = new LocalFunctionElementX( |
570 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement); | 576 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement); |
571 ResolverTask.processAsyncMarker(compiler, function, registry); | 577 ResolverTask.processAsyncMarker(compiler, function, registry); |
572 function.functionSignature = SignatureResolver.analyze( | 578 function.functionSignature = SignatureResolver.analyze( |
573 compiler, node.parameters, node.returnType, function, registry, | 579 compiler, |
580 scope, | |
581 node.typeVariables, | |
582 node.parameters, | |
583 node.returnType, | |
584 function, | |
585 registry, | |
574 createRealParameters: true, | 586 createRealParameters: true, |
575 isFunctionExpression: !inFunctionDeclaration); | 587 isFunctionExpression: !inFunctionDeclaration); |
576 checkLocalDefinitionName(node, function); | 588 checkLocalDefinitionName(node, function); |
577 registry.defineFunction(node, function); | 589 registry.defineFunction(node, function); |
578 if (doAddToScope) { | 590 if (doAddToScope) { |
579 addToScope(function); | 591 addToScope(function); |
580 } | 592 } |
581 Scope oldScope = scope; // The scope is modified by [setupFunction]. | 593 Scope oldScope = scope; // The scope is modified by [setupFunction]. |
582 setupFunction(node, function); | 594 setupFunction(node, function); |
583 | 595 |
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1857 | 1869 |
1858 /// Handle access to a type literal of type variable [element]. Like `T` or | 1870 /// Handle access to a type literal of type variable [element]. Like `T` or |
1859 /// `T()` where 'T' is type variable. | 1871 /// `T()` where 'T' is type variable. |
1860 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the | 1872 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
1861 // the [GetStructure]. | 1873 // the [GetStructure]. |
1862 // TODO(johnniwinther): Remove [element] when it is no longer needed for | 1874 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
1863 // evaluating constants. | 1875 // evaluating constants. |
1864 ResolutionResult handleTypeVariableTypeLiteralAccess( | 1876 ResolutionResult handleTypeVariableTypeLiteralAccess( |
1865 Send node, Name name, TypeVariableElement element) { | 1877 Send node, Name name, TypeVariableElement element) { |
1866 AccessSemantics semantics; | 1878 AccessSemantics semantics; |
1867 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { | 1879 if (!Elements.hasAccessToTypeVariables(enclosingElement) && |
Johnni Winther
2016/04/29 07:21:06
Move the check of `element.typeDeclaration is Type
eernst
2016/04/29 13:24:50
Done.
| |
1880 element.typeDeclaration is TypeDeclarationElement) { | |
1868 // TODO(johnniwinther): Add another access semantics for this. | 1881 // TODO(johnniwinther): Add another access semantics for this. |
1869 ErroneousElement error = reportAndCreateErroneousElement( | 1882 ErroneousElement error = reportAndCreateErroneousElement( |
1870 node, | 1883 node, |
1871 name.text, | 1884 name.text, |
1872 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1885 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
1873 {'typeVariableName': name}, | 1886 {'typeVariableName': name}, |
1874 isError: true); | 1887 isError: true); |
1875 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 1888 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
1876 semantics = new StaticAccess.invalid(error); | 1889 semantics = new StaticAccess.invalid(error); |
1877 // TODO(johnniwinther): Clean up registration of elements and selectors | 1890 // TODO(johnniwinther): Clean up registration of elements and selectors |
(...skipping 20 matching lines...) Expand all Loading... | |
1898 registry.registerSendStructure(node, new GetStructure(semantics)); | 1911 registry.registerSendStructure(node, new GetStructure(semantics)); |
1899 } | 1912 } |
1900 return const NoneResult(); | 1913 return const NoneResult(); |
1901 } | 1914 } |
1902 | 1915 |
1903 /// Handle access to a type literal of type variable [element]. Like `T = b`, | 1916 /// Handle access to a type literal of type variable [element]. Like `T = b`, |
1904 /// `T++` or `T += b` where 'T' is type variable. | 1917 /// `T++` or `T += b` where 'T' is type variable. |
1905 ResolutionResult handleTypeVariableTypeLiteralUpdate( | 1918 ResolutionResult handleTypeVariableTypeLiteralUpdate( |
1906 SendSet node, Name name, TypeVariableElement element) { | 1919 SendSet node, Name name, TypeVariableElement element) { |
1907 AccessSemantics semantics; | 1920 AccessSemantics semantics; |
1908 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { | 1921 if (!Elements.hasAccessToTypeVariables(enclosingElement) && |
1922 element.typeDeclaration is TypeDeclarationElement) { | |
1909 // TODO(johnniwinther): Add another access semantics for this. | 1923 // TODO(johnniwinther): Add another access semantics for this. |
1910 ErroneousElement error = reportAndCreateErroneousElement( | 1924 ErroneousElement error = reportAndCreateErroneousElement( |
1911 node, | 1925 node, |
1912 name.text, | 1926 name.text, |
1913 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1927 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
1914 {'typeVariableName': name}, | 1928 {'typeVariableName': name}, |
1915 isError: true); | 1929 isError: true); |
1916 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 1930 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
1917 semantics = new StaticAccess.invalid(error); | 1931 semantics = new StaticAccess.invalid(error); |
1918 } else { | 1932 } else { |
(...skipping 2752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4671 } | 4685 } |
4672 return const NoneResult(); | 4686 return const NoneResult(); |
4673 } | 4687 } |
4674 } | 4688 } |
4675 | 4689 |
4676 /// Looks up [name] in [scope] and unwraps the result. | 4690 /// Looks up [name] in [scope] and unwraps the result. |
4677 Element lookupInScope( | 4691 Element lookupInScope( |
4678 DiagnosticReporter reporter, Node node, Scope scope, String name) { | 4692 DiagnosticReporter reporter, Node node, Scope scope, String name) { |
4679 return Elements.unwrap(scope.lookup(name), reporter, node); | 4693 return Elements.unwrap(scope.lookup(name), reporter, node); |
4680 } | 4694 } |
OLD | NEW |