@@ -48,9 +48,9 @@ class EnclosingExecutableContext {
4848 final ExecutableElement element;
4949 final bool isAsynchronous;
5050 final bool isConstConstructor;
51- final bool isFactoryConstructor;
5251 final bool isGenerativeConstructor;
5352 final bool isGenerator;
53+ final bool inFactoryConstructor;
5454 final bool inStaticMethod;
5555
5656 /// The return statements that have a value.
@@ -66,11 +66,10 @@ class EnclosingExecutableContext {
6666 EnclosingExecutableContext (this .element)
6767 : isAsynchronous = element != null && element.isAsynchronous,
6868 isConstConstructor = element is ConstructorElement && element.isConst,
69- isFactoryConstructor =
70- element is ConstructorElement && element.isFactory,
7169 isGenerativeConstructor =
7270 element is ConstructorElement && ! element.isFactory,
7371 isGenerator = element != null && element.isGenerator,
72+ inFactoryConstructor = _inFactoryConstructor (element),
7473 inStaticMethod = _inStaticMethod (element);
7574
7675 EnclosingExecutableContext .empty () : this (null );
@@ -84,7 +83,7 @@ class EnclosingExecutableContext {
8483 ? className
8584 : '$className .$constructorName ' ;
8685 } else {
87- return element.displayName;
86+ return element? .displayName;
8887 }
8988 }
9089
@@ -107,6 +106,17 @@ class EnclosingExecutableContext {
107106
108107 DartType get returnType => element.returnType;
109108
109+ static bool _inFactoryConstructor (ExecutableElement element) {
110+ if (element is ConstructorElement ) {
111+ return element.isFactory;
112+ }
113+ var enclosing = element? .enclosingElement;
114+ if (enclosing is ExecutableElement ) {
115+ return _inFactoryConstructor (enclosing);
116+ }
117+ return false ;
118+ }
119+
110120 static bool _inStaticMethod (ExecutableElement element) {
111121 var enclosing = element? .enclosingElement;
112122 if (enclosing is ClassElement || enclosing is ExtensionElement ) {
@@ -1129,7 +1139,7 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
11291139 void visitSimpleIdentifier (SimpleIdentifier node) {
11301140 _checkForAmbiguousImport (node);
11311141 _checkForReferenceBeforeDeclaration (node);
1132- _checkForImplicitThisReferenceInInitializer (node);
1142+ _checkForInvalidInstanceMemberAccess (node);
11331143 _checkForTypeParameterReferencedByStatic (node);
11341144 if (! _isUnqualifiedReferenceToNonLocalStaticMemberAllowed (node)) {
11351145 _checkForUnqualifiedReferenceToNonLocalStaticMember (node);
@@ -2773,76 +2783,6 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
27732783 }
27742784 }
27752785
2776- /// Verify that if the given [identifier] is part of a constructor
2777- /// initializer, then it does not implicitly reference 'this' expression.
2778- ///
2779- /// See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER] , and
2780- /// [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC] .
2781- /// TODO(scheglov) rename thid method
2782- void _checkForImplicitThisReferenceInInitializer (
2783- SimpleIdentifier identifier) {
2784- if (_isInComment) {
2785- return ;
2786- }
2787- if (! _isInConstructorInitializer &&
2788- ! _enclosingExecutable.inStaticMethod &&
2789- ! _enclosingExecutable.isFactoryConstructor &&
2790- ! _isInInstanceNotLateVariableDeclaration &&
2791- ! _isInStaticVariableDeclaration) {
2792- return ;
2793- }
2794- // prepare element
2795- Element element = identifier.writeOrReadElement;
2796- if (! (element is MethodElement || element is PropertyAccessorElement )) {
2797- return ;
2798- }
2799- // static element
2800- ExecutableElement executableElement = element as ExecutableElement ;
2801- if (executableElement.isStatic) {
2802- return ;
2803- }
2804- // not a class member
2805- Element enclosingElement = element.enclosingElement;
2806- if (enclosingElement is ! ClassElement &&
2807- enclosingElement is ! ExtensionElement ) {
2808- return ;
2809- }
2810- // qualified method invocation
2811- AstNode parent = identifier.parent;
2812- if (parent is MethodInvocation ) {
2813- if (identical (parent.methodName, identifier) &&
2814- parent.realTarget != null ) {
2815- return ;
2816- }
2817- }
2818- // qualified property access
2819- if (parent is PropertyAccess ) {
2820- if (identical (parent.propertyName, identifier) &&
2821- parent.realTarget != null ) {
2822- return ;
2823- }
2824- }
2825- if (parent is PrefixedIdentifier ) {
2826- if (identical (parent.identifier, identifier)) {
2827- return ;
2828- }
2829- }
2830-
2831- if (_enclosingExecutable.inStaticMethod) {
2832- // TODO
2833- _errorReporter.reportErrorForNode (
2834- CompileTimeErrorCode .INSTANCE_MEMBER_ACCESS_FROM_STATIC , identifier);
2835- } else if (_enclosingExecutable.isFactoryConstructor) {
2836- _errorReporter.reportErrorForNode (
2837- CompileTimeErrorCode .INSTANCE_MEMBER_ACCESS_FROM_FACTORY , identifier);
2838- } else {
2839- _errorReporter.reportErrorForNode (
2840- CompileTimeErrorCode .IMPLICIT_THIS_REFERENCE_IN_INITIALIZER ,
2841- identifier,
2842- [identifier.name]);
2843- }
2844- }
2845-
28462786 /// Check that if the visiting library is not system, then any given library
28472787 /// should not be SDK internal library. The [importElement] is the
28482788 /// [ImportElement] retrieved from the node, if the element in the node was
@@ -3011,6 +2951,74 @@ class ErrorVerifier extends RecursiveAstVisitor<void> {
30112951 }
30122952 }
30132953
2954+ /// Verify that if the given [identifier] is part of a constructor
2955+ /// initializer, then it does not implicitly reference 'this' expression.
2956+ ///
2957+ /// See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER] ,
2958+ /// [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY] , and
2959+ /// [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC] .
2960+ void _checkForInvalidInstanceMemberAccess (SimpleIdentifier identifier) {
2961+ if (_isInComment) {
2962+ return ;
2963+ }
2964+ if (! _isInConstructorInitializer &&
2965+ ! _enclosingExecutable.inStaticMethod &&
2966+ ! _enclosingExecutable.inFactoryConstructor &&
2967+ ! _isInInstanceNotLateVariableDeclaration &&
2968+ ! _isInStaticVariableDeclaration) {
2969+ return ;
2970+ }
2971+ // prepare element
2972+ Element element = identifier.writeOrReadElement;
2973+ if (! (element is MethodElement || element is PropertyAccessorElement )) {
2974+ return ;
2975+ }
2976+ // static element
2977+ ExecutableElement executableElement = element as ExecutableElement ;
2978+ if (executableElement.isStatic) {
2979+ return ;
2980+ }
2981+ // not a class member
2982+ Element enclosingElement = element.enclosingElement;
2983+ if (enclosingElement is ! ClassElement &&
2984+ enclosingElement is ! ExtensionElement ) {
2985+ return ;
2986+ }
2987+ // qualified method invocation
2988+ AstNode parent = identifier.parent;
2989+ if (parent is MethodInvocation ) {
2990+ if (identical (parent.methodName, identifier) &&
2991+ parent.realTarget != null ) {
2992+ return ;
2993+ }
2994+ }
2995+ // qualified property access
2996+ if (parent is PropertyAccess ) {
2997+ if (identical (parent.propertyName, identifier) &&
2998+ parent.realTarget != null ) {
2999+ return ;
3000+ }
3001+ }
3002+ if (parent is PrefixedIdentifier ) {
3003+ if (identical (parent.identifier, identifier)) {
3004+ return ;
3005+ }
3006+ }
3007+
3008+ if (_enclosingExecutable.inStaticMethod) {
3009+ _errorReporter.reportErrorForNode (
3010+ CompileTimeErrorCode .INSTANCE_MEMBER_ACCESS_FROM_STATIC , identifier);
3011+ } else if (_enclosingExecutable.inFactoryConstructor) {
3012+ _errorReporter.reportErrorForNode (
3013+ CompileTimeErrorCode .INSTANCE_MEMBER_ACCESS_FROM_FACTORY , identifier);
3014+ } else {
3015+ _errorReporter.reportErrorForNode (
3016+ CompileTimeErrorCode .IMPLICIT_THIS_REFERENCE_IN_INITIALIZER ,
3017+ identifier,
3018+ [identifier.name]);
3019+ }
3020+ }
3021+
30143022 /// Check to see whether the given function [body] has a modifier associated
30153023 /// with it, and report it as an error if it does.
30163024 void _checkForInvalidModifierOnBody (
0 commit comments