| Index: dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/hint/BestPracticesVerifier.java
|
| ===================================================================
|
| --- dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/hint/BestPracticesVerifier.java (revision 29808)
|
| +++ dart/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/hint/BestPracticesVerifier.java (working copy)
|
| @@ -13,19 +13,32 @@
|
| */
|
| package com.google.dart.engine.internal.hint;
|
|
|
| +import com.google.dart.engine.ast.ASTNode;
|
| import com.google.dart.engine.ast.AsExpression;
|
| +import com.google.dart.engine.ast.AssignmentExpression;
|
| import com.google.dart.engine.ast.BinaryExpression;
|
| import com.google.dart.engine.ast.ClassDeclaration;
|
| +import com.google.dart.engine.ast.ConstructorName;
|
| +import com.google.dart.engine.ast.ExportDirective;
|
| import com.google.dart.engine.ast.Expression;
|
| import com.google.dart.engine.ast.Identifier;
|
| +import com.google.dart.engine.ast.ImportDirective;
|
| +import com.google.dart.engine.ast.IndexExpression;
|
| +import com.google.dart.engine.ast.InstanceCreationExpression;
|
| import com.google.dart.engine.ast.IsExpression;
|
| import com.google.dart.engine.ast.MethodDeclaration;
|
| import com.google.dart.engine.ast.MethodInvocation;
|
| import com.google.dart.engine.ast.NullLiteral;
|
| import com.google.dart.engine.ast.ParenthesizedExpression;
|
| +import com.google.dart.engine.ast.PostfixExpression;
|
| +import com.google.dart.engine.ast.PrefixExpression;
|
| +import com.google.dart.engine.ast.RedirectingConstructorInvocation;
|
| +import com.google.dart.engine.ast.SimpleIdentifier;
|
| +import com.google.dart.engine.ast.SuperConstructorInvocation;
|
| import com.google.dart.engine.ast.TypeName;
|
| import com.google.dart.engine.ast.visitor.RecursiveASTVisitor;
|
| import com.google.dart.engine.element.ClassElement;
|
| +import com.google.dart.engine.element.ConstructorElement;
|
| import com.google.dart.engine.element.Element;
|
| import com.google.dart.engine.element.ExecutableElement;
|
| import com.google.dart.engine.element.LibraryElement;
|
| @@ -105,8 +118,18 @@
|
| }
|
|
|
| @Override
|
| + public Void visitAssignmentExpression(AssignmentExpression node) {
|
| + TokenType operatorType = node.getOperator().getType();
|
| + if (operatorType != TokenType.EQ) {
|
| + checkForDeprecatedMemberUse(node.getBestElement(), node);
|
| + }
|
| + return super.visitAssignmentExpression(node);
|
| + }
|
| +
|
| + @Override
|
| public Void visitBinaryExpression(BinaryExpression node) {
|
| checkForDivisionOptimizationHint(node);
|
| + checkForDeprecatedMemberUse(node.getBestElement(), node);
|
| return super.visitBinaryExpression(node);
|
| }
|
|
|
| @@ -124,6 +147,30 @@
|
| }
|
|
|
| @Override
|
| + public Void visitExportDirective(ExportDirective node) {
|
| + checkForDeprecatedMemberUse(node.getUriElement(), node);
|
| + return super.visitExportDirective(node);
|
| + }
|
| +
|
| + @Override
|
| + public Void visitImportDirective(ImportDirective node) {
|
| + checkForDeprecatedMemberUse(node.getUriElement(), node);
|
| + return super.visitImportDirective(node);
|
| + }
|
| +
|
| + @Override
|
| + public Void visitIndexExpression(IndexExpression node) {
|
| + checkForDeprecatedMemberUse(node.getBestElement(), node);
|
| + return super.visitIndexExpression(node);
|
| + }
|
| +
|
| + @Override
|
| + public Void visitInstanceCreationExpression(InstanceCreationExpression node) {
|
| + checkForDeprecatedMemberUse(node.getStaticElement(), node);
|
| + return super.visitInstanceCreationExpression(node);
|
| + }
|
| +
|
| + @Override
|
| public Void visitIsExpression(IsExpression node) {
|
| checkAllTypeChecks(node);
|
| return super.visitIsExpression(node);
|
| @@ -131,11 +178,40 @@
|
|
|
| @Override
|
| public Void visitMethodDeclaration(MethodDeclaration node) {
|
| - // Commented out until we decide that we want this hint in the analyzer
|
| checkForOverridingPrivateMember(node);
|
| return super.visitMethodDeclaration(node);
|
| }
|
|
|
| + @Override
|
| + public Void visitPostfixExpression(PostfixExpression node) {
|
| + checkForDeprecatedMemberUse(node.getBestElement(), node);
|
| + return super.visitPostfixExpression(node);
|
| + }
|
| +
|
| + @Override
|
| + public Void visitPrefixExpression(PrefixExpression node) {
|
| + checkForDeprecatedMemberUse(node.getBestElement(), node);
|
| + return super.visitPrefixExpression(node);
|
| + }
|
| +
|
| + @Override
|
| + public Void visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
|
| + checkForDeprecatedMemberUse(node.getStaticElement(), node);
|
| + return super.visitRedirectingConstructorInvocation(node);
|
| + }
|
| +
|
| + @Override
|
| + public Void visitSimpleIdentifier(SimpleIdentifier node) {
|
| + checkForDeprecatedMemberUse(node);
|
| + return super.visitSimpleIdentifier(node);
|
| + }
|
| +
|
| + @Override
|
| + public Void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
|
| + checkForDeprecatedMemberUse(node.getStaticElement(), node);
|
| + return super.visitSuperConstructorInvocation(node);
|
| + }
|
| +
|
| /**
|
| * Check for the passed is expression for the unnecessary type check hint codes as well as null
|
| * checks expressed using an is expression.
|
| @@ -196,6 +272,56 @@
|
| }
|
|
|
| /**
|
| + * Given some {@link Element}, look at the associated metadata and report the use of the member if
|
| + * it is declared as deprecated.
|
| + *
|
| + * @param element some element to check for deprecated use of
|
| + * @param node the node use for the location of the error
|
| + * @return {@code true} if and only if a hint code is generated on the passed node
|
| + * @see HintCode#DEPRECATED_MEMBER_USE
|
| + */
|
| + private boolean checkForDeprecatedMemberUse(Element element, ASTNode node) {
|
| + if (element != null && element.isDeprecated()) {
|
| + String displayName = element.getDisplayName();
|
| + if (element instanceof ConstructorElement) {
|
| + // TODO(jwren) We should modify ConstructorElement.getDisplayName(), or have the logic
|
| + // centralized elsewhere, instead of doing this logic here.
|
| + ConstructorElement constructorElement = (ConstructorElement) element;
|
| + displayName = constructorElement.getEnclosingElement().getDisplayName();
|
| + if (!constructorElement.getDisplayName().isEmpty()) {
|
| + displayName = displayName + '.' + constructorElement.getDisplayName();
|
| + }
|
| + }
|
| + errorReporter.reportError(HintCode.DEPRECATED_MEMBER_USE, node, displayName);
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + /**
|
| + * For {@link SimpleIdentifier}s, only call {@link #checkForDeprecatedMemberUse(Element, ASTNode)}
|
| + * if the node is not in a declaration context.
|
| + * <p>
|
| + * Also, if the identifier is a constructor name in a constructor invocation, then calls to the
|
| + * deprecated constructor will be caught by
|
| + * {@link #visitInstanceCreationExpression(InstanceCreationExpression)} and
|
| + * {@link #visitSuperConstructorInvocation(SuperConstructorInvocation)}, and can be ignored by
|
| + * this visit method.
|
| + *
|
| + * @param identifier some simple identifier to check for deprecated use of
|
| + * @return {@code true} if and only if a hint code is generated on the passed node
|
| + * @see HintCode#DEPRECATED_MEMBER_USE
|
| + */
|
| + private boolean checkForDeprecatedMemberUse(SimpleIdentifier identifier) {
|
| + if (identifier.inDeclarationContext()
|
| + || (identifier.getParent() instanceof ConstructorName && identifier == ((ConstructorName) identifier.getParent()).getName())
|
| + || (identifier.getParent() instanceof SuperConstructorInvocation && identifier == ((SuperConstructorInvocation) identifier.getParent()).getConstructorName())) {
|
| + return false;
|
| + }
|
| + return checkForDeprecatedMemberUse(identifier.getBestElement(), identifier);
|
| + }
|
| +
|
| + /**
|
| * Check for the passed binary expression for the {@link HintCode#DIVISION_OPTIMIZATION}.
|
| *
|
| * @param node the binary expression to check
|
|
|