| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013, the Dart project authors. | 2 * Copyright (c) 2013, the Dart project authors. |
| 3 * | 3 * |
| 4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except | 4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except |
| 5 * in compliance with the License. You may obtain a copy of the License at | 5 * in compliance with the License. You may obtain a copy of the License at |
| 6 * | 6 * |
| 7 * http://www.eclipse.org/legal/epl-v10.html | 7 * http://www.eclipse.org/legal/epl-v10.html |
| 8 * | 8 * |
| 9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License | 9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License |
| 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express | 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 * formal, and finally, initialized in the initializers list. | 166 * formal, and finally, initialized in the initializers list. |
| 167 */ | 167 */ |
| 168 private enum INIT_STATE { | 168 private enum INIT_STATE { |
| 169 NOT_INIT, | 169 NOT_INIT, |
| 170 INIT_IN_DECLARATION, | 170 INIT_IN_DECLARATION, |
| 171 INIT_IN_FIELD_FORMAL, | 171 INIT_IN_FIELD_FORMAL, |
| 172 INIT_IN_INITIALIZERS | 172 INIT_IN_INITIALIZERS |
| 173 } | 173 } |
| 174 | 174 |
| 175 /** | 175 /** |
| 176 * Checks if the given expression is the reference to the type. | |
| 177 * | |
| 178 * @param expr the expression to evaluate | |
| 179 * @return {@code true} if the given expression is the reference to the type | |
| 180 */ | |
| 181 private static boolean isTypeReference(Expression expr) { | |
| 182 if (expr instanceof Identifier) { | |
| 183 Identifier identifier = (Identifier) expr; | |
| 184 return identifier.getStaticElement() instanceof ClassElement; | |
| 185 } | |
| 186 return false; | |
| 187 } | |
| 188 | |
| 189 /** | |
| 190 * The error reporter by which errors will be reported. | 176 * The error reporter by which errors will be reported. |
| 191 */ | 177 */ |
| 192 private ErrorReporter errorReporter; | 178 private ErrorReporter errorReporter; |
| 193 | 179 |
| 194 /** | 180 /** |
| 195 * The current library that is being analyzed. | 181 * The current library that is being analyzed. |
| 196 */ | 182 */ |
| 197 private LibraryElement currentLibrary; | 183 private LibraryElement currentLibrary; |
| 198 | 184 |
| 199 /** | 185 /** |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 } finally { | 807 } finally { |
| 822 enclosingFunction = previousFunction; | 808 enclosingFunction = previousFunction; |
| 823 isInStaticMethod = false; | 809 isInStaticMethod = false; |
| 824 } | 810 } |
| 825 } | 811 } |
| 826 | 812 |
| 827 @Override | 813 @Override |
| 828 public Void visitMethodInvocation(MethodInvocation node) { | 814 public Void visitMethodInvocation(MethodInvocation node) { |
| 829 Expression target = node.getRealTarget(); | 815 Expression target = node.getRealTarget(); |
| 830 SimpleIdentifier methodName = node.getMethodName(); | 816 SimpleIdentifier methodName = node.getMethodName(); |
| 831 checkForStaticAccessToInstanceMember(target, methodName); | 817 if (target != null) { |
| 832 checkForInstanceAccessToStaticMember(target, methodName); | 818 ClassElement typeReference = ElementResolver.getTypeReference(target); |
| 833 if (target == null) { | 819 checkForStaticAccessToInstanceMember(typeReference, methodName); |
| 820 checkForInstanceAccessToStaticMember(typeReference, methodName); |
| 821 } else { |
| 834 checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); | 822 checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); |
| 835 } | 823 } |
| 836 return super.visitMethodInvocation(node); | 824 return super.visitMethodInvocation(node); |
| 837 } | 825 } |
| 838 | 826 |
| 839 @Override | 827 @Override |
| 840 public Void visitNativeClause(NativeClause node) { | 828 public Void visitNativeClause(NativeClause node) { |
| 841 // TODO(brianwilkerson) Figure out the right rule for when 'native' is allow
ed. | 829 // TODO(brianwilkerson) Figure out the right rule for when 'native' is allow
ed. |
| 842 if (!isInSystemLibrary) { | 830 if (!isInSystemLibrary) { |
| 843 errorReporter.reportError(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, n
ode); | 831 errorReporter.reportError(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, n
ode); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 854 @Override | 842 @Override |
| 855 public Void visitPostfixExpression(PostfixExpression node) { | 843 public Void visitPostfixExpression(PostfixExpression node) { |
| 856 checkForAssignmentToFinal(node.getOperand()); | 844 checkForAssignmentToFinal(node.getOperand()); |
| 857 checkForIntNotAssignable(node.getOperand()); | 845 checkForIntNotAssignable(node.getOperand()); |
| 858 return super.visitPostfixExpression(node); | 846 return super.visitPostfixExpression(node); |
| 859 } | 847 } |
| 860 | 848 |
| 861 @Override | 849 @Override |
| 862 public Void visitPrefixedIdentifier(PrefixedIdentifier node) { | 850 public Void visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 863 if (!(node.getParent() instanceof Annotation)) { | 851 if (!(node.getParent() instanceof Annotation)) { |
| 864 checkForStaticAccessToInstanceMember(node.getPrefix(), node.getIdentifier(
)); | 852 ClassElement typeReference = ElementResolver.getTypeReference(node.getPref
ix()); |
| 865 checkForInstanceAccessToStaticMember(node.getPrefix(), node.getIdentifier(
)); | 853 SimpleIdentifier name = node.getIdentifier(); |
| 854 checkForStaticAccessToInstanceMember(typeReference, name); |
| 855 checkForInstanceAccessToStaticMember(typeReference, name); |
| 866 } | 856 } |
| 867 return super.visitPrefixedIdentifier(node); | 857 return super.visitPrefixedIdentifier(node); |
| 868 } | 858 } |
| 869 | 859 |
| 870 @Override | 860 @Override |
| 871 public Void visitPrefixExpression(PrefixExpression node) { | 861 public Void visitPrefixExpression(PrefixExpression node) { |
| 872 TokenType operatorType = node.getOperator().getType(); | 862 TokenType operatorType = node.getOperator().getType(); |
| 873 Expression operand = node.getOperand(); | 863 Expression operand = node.getOperand(); |
| 874 if (operatorType == TokenType.BANG) { | 864 if (operatorType == TokenType.BANG) { |
| 875 checkForNonBoolNegationExpression(operand); | 865 checkForNonBoolNegationExpression(operand); |
| 876 } else if (operatorType.isIncrementOperator()) { | 866 } else if (operatorType.isIncrementOperator()) { |
| 877 checkForAssignmentToFinal(operand); | 867 checkForAssignmentToFinal(operand); |
| 878 } | 868 } |
| 879 checkForIntNotAssignable(operand); | 869 checkForIntNotAssignable(operand); |
| 880 return super.visitPrefixExpression(node); | 870 return super.visitPrefixExpression(node); |
| 881 } | 871 } |
| 882 | 872 |
| 883 @Override | 873 @Override |
| 884 public Void visitPropertyAccess(PropertyAccess node) { | 874 public Void visitPropertyAccess(PropertyAccess node) { |
| 885 Expression target = node.getRealTarget(); | 875 ClassElement typeReference = ElementResolver.getTypeReference(node.getRealTa
rget()); |
| 886 SimpleIdentifier propertyName = node.getPropertyName(); | 876 SimpleIdentifier propertyName = node.getPropertyName(); |
| 887 checkForStaticAccessToInstanceMember(target, propertyName); | 877 checkForStaticAccessToInstanceMember(typeReference, propertyName); |
| 888 checkForInstanceAccessToStaticMember(target, propertyName); | 878 checkForInstanceAccessToStaticMember(typeReference, propertyName); |
| 889 return super.visitPropertyAccess(node); | 879 return super.visitPropertyAccess(node); |
| 890 } | 880 } |
| 891 | 881 |
| 892 @Override | 882 @Override |
| 893 public Void visitRedirectingConstructorInvocation(RedirectingConstructorInvoca
tion node) { | 883 public Void visitRedirectingConstructorInvocation(RedirectingConstructorInvoca
tion node) { |
| 894 isInConstructorInitializer = true; | 884 isInConstructorInitializer = true; |
| 895 try { | 885 try { |
| 896 return super.visitRedirectingConstructorInvocation(node); | 886 return super.visitRedirectingConstructorInvocation(node); |
| 897 } finally { | 887 } finally { |
| 898 isInConstructorInitializer = false; | 888 isInConstructorInitializer = false; |
| (...skipping 2418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3317 if (errors == null || errors.isEmpty()) { | 3307 if (errors == null || errors.isEmpty()) { |
| 3318 return false; | 3308 return false; |
| 3319 } | 3309 } |
| 3320 for (AnalysisError error : errors) { | 3310 for (AnalysisError error : errors) { |
| 3321 errorReporter.reportError(error); | 3311 errorReporter.reportError(error); |
| 3322 } | 3312 } |
| 3323 return true; | 3313 return true; |
| 3324 } | 3314 } |
| 3325 | 3315 |
| 3326 /** | 3316 /** |
| 3327 * This checks that if the given "target" is not a type reference then the "na
me" is reference to | 3317 * This checks the given "typeReference" is not a type reference and that then
the "name" is |
| 3328 * an instance member. | 3318 * reference to an instance member. |
| 3329 * | 3319 * |
| 3330 * @param target the target of the name access to evaluate | 3320 * @param typeReference the resolved {@link ClassElement} of the left hand sid
e of the expression, |
| 3321 * or {@code null}, aka, the class element of 'C' in 'C.x', see |
| 3322 * {@link #getTypeReference(Expression)} |
| 3331 * @param name the accessed name to evaluate | 3323 * @param name the accessed name to evaluate |
| 3332 * @return {@code true} if and only if an error code is generated on the passe
d node | 3324 * @return {@code true} if and only if an error code is generated on the passe
d node |
| 3333 * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER | 3325 * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER |
| 3334 */ | 3326 */ |
| 3335 private boolean checkForInstanceAccessToStaticMember(Expression target, Simple
Identifier name) { | 3327 private boolean checkForInstanceAccessToStaticMember(ClassElement typeReferenc
e, |
| 3336 // OK, no target | 3328 SimpleIdentifier name) { |
| 3337 if (target == null) { | 3329 // OK, in comment |
| 3330 if (isInComment) { |
| 3338 return false; | 3331 return false; |
| 3339 } | 3332 } |
| 3340 // OK, in comment | 3333 // OK, target is a type |
| 3341 if (isInComment) { | 3334 if (typeReference != null) { |
| 3342 return false; | 3335 return false; |
| 3343 } | 3336 } |
| 3344 // prepare member Element | 3337 // prepare member Element |
| 3345 Element element = name.getStaticElement(); | 3338 Element element = name.getStaticElement(); |
| 3346 if (!(element instanceof ExecutableElement)) { | 3339 if (!(element instanceof ExecutableElement)) { |
| 3347 return false; | 3340 return false; |
| 3348 } | 3341 } |
| 3349 ExecutableElement executableElement = (ExecutableElement) element; | 3342 ExecutableElement executableElement = (ExecutableElement) element; |
| 3350 // OK, top-level element | 3343 // OK, top-level element |
| 3351 if (!(executableElement.getEnclosingElement() instanceof ClassElement)) { | 3344 if (!(executableElement.getEnclosingElement() instanceof ClassElement)) { |
| 3352 return false; | 3345 return false; |
| 3353 } | 3346 } |
| 3354 // OK, instance member | 3347 // OK, instance member |
| 3355 if (!executableElement.isStatic()) { | 3348 if (!executableElement.isStatic()) { |
| 3356 return false; | 3349 return false; |
| 3357 } | 3350 } |
| 3358 // OK, target is a type | |
| 3359 if (isTypeReference(target)) { | |
| 3360 return false; | |
| 3361 } | |
| 3362 // report problem | 3351 // report problem |
| 3363 errorReporter.reportError( | 3352 errorReporter.reportError( |
| 3364 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, | 3353 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, |
| 3365 name, | 3354 name, |
| 3366 name.getName()); | 3355 name.getName()); |
| 3367 return true; | 3356 return true; |
| 3368 } | 3357 } |
| 3369 | 3358 |
| 3370 /** | 3359 /** |
| 3371 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given | 3360 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given |
| (...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4571 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | 4560 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, |
| 4572 returnExpression, | 4561 returnExpression, |
| 4573 staticReturnType.getDisplayName(), | 4562 staticReturnType.getDisplayName(), |
| 4574 expectedReturnType.getDisplayName(), | 4563 expectedReturnType.getDisplayName(), |
| 4575 enclosingFunction.getDisplayName()); | 4564 enclosingFunction.getDisplayName()); |
| 4576 return true; | 4565 return true; |
| 4577 } | 4566 } |
| 4578 } | 4567 } |
| 4579 | 4568 |
| 4580 /** | 4569 /** |
| 4581 * This checks that if the given "target" is the type reference then the "name
" is not the | 4570 * This checks the given "typeReference" and that the "name" is not the refere
nce to an instance |
| 4582 * reference to a instance member. | 4571 * member. |
| 4583 * | 4572 * |
| 4584 * @param target the target of the name access to evaluate | 4573 * @param typeReference the resolved {@link ClassElement} of the left hand sid
e of the expression, |
| 4574 * or {@code null}, aka, the class element of 'C' in 'C.x', see |
| 4575 * {@link #getTypeReference(Expression)} |
| 4585 * @param name the accessed name to evaluate | 4576 * @param name the accessed name to evaluate |
| 4586 * @return {@code true} if and only if an error code is generated on the passe
d node | 4577 * @return {@code true} if and only if an error code is generated on the passe
d node |
| 4587 * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER | 4578 * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER |
| 4588 */ | 4579 */ |
| 4589 private boolean checkForStaticAccessToInstanceMember(Expression target, Simple
Identifier name) { | 4580 private boolean checkForStaticAccessToInstanceMember(ClassElement typeReferenc
e, |
| 4581 SimpleIdentifier name) { |
| 4582 // OK, target is not a type |
| 4583 if (typeReference == null) { |
| 4584 return false; |
| 4585 } |
| 4590 // prepare member Element | 4586 // prepare member Element |
| 4591 Element element = name.getStaticElement(); | 4587 Element element = name.getStaticElement(); |
| 4592 if (!(element instanceof ExecutableElement)) { | 4588 if (!(element instanceof ExecutableElement)) { |
| 4593 return false; | 4589 return false; |
| 4594 } | 4590 } |
| 4595 ExecutableElement memberElement = (ExecutableElement) element; | 4591 ExecutableElement memberElement = (ExecutableElement) element; |
| 4596 // OK, static | 4592 // OK, static |
| 4597 if (memberElement.isStatic()) { | 4593 if (memberElement.isStatic()) { |
| 4598 return false; | 4594 return false; |
| 4599 } | 4595 } |
| 4600 // OK, target is not a type | |
| 4601 if (!isTypeReference(target)) { | |
| 4602 return false; | |
| 4603 } | |
| 4604 // report problem | 4596 // report problem |
| 4605 errorReporter.reportError( | 4597 errorReporter.reportError( |
| 4606 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, | 4598 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, |
| 4607 name, | 4599 name, |
| 4608 name.getName()); | 4600 name.getName()); |
| 4609 return true; | 4601 return true; |
| 4610 } | 4602 } |
| 4611 | 4603 |
| 4612 /** | 4604 /** |
| 4613 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the | 4605 * This checks that the type of the passed 'switch' expression is assignable t
o the type of the |
| (...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5407 if (superClassElt != null) { | 5399 if (superClassElt != null) { |
| 5408 return memberHasConcreteMethodImplementationInSuperclassChain( | 5400 return memberHasConcreteMethodImplementationInSuperclassChain( |
| 5409 superClassElt, | 5401 superClassElt, |
| 5410 methodName, | 5402 methodName, |
| 5411 superclassChain); | 5403 superclassChain); |
| 5412 } | 5404 } |
| 5413 } | 5405 } |
| 5414 return false; | 5406 return false; |
| 5415 } | 5407 } |
| 5416 } | 5408 } |
| OLD | NEW |