Package org.aspectj.org.eclipse.jdt.internal.codeassist

Source Code of org.aspectj.org.eclipse.jdt.internal.codeassist.ThrownExceptionFinder

/*******************************************************************************
* Copyright (c) 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.codeassist;

import java.util.Stack;

import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Block;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.util.SimpleSet;

public class ThrownExceptionFinder extends ASTVisitor {

  private SimpleSet thrownExceptions;
  private Stack exceptionsStack;
 
  public ReferenceBinding[] find(TryStatement tryStatement, BlockScope scope) {
    this.thrownExceptions = new SimpleSet();
    this.exceptionsStack = new Stack();
    tryStatement.traverse(this, scope);
    removeCaughtExceptions(tryStatement);
   
    ReferenceBinding[] result = new ReferenceBinding[this.thrownExceptions.elementSize];
    this.thrownExceptions.asArray(result);
    return result;
  }

  private void acceptException(ReferenceBinding binding) {
    if (binding != null && binding.isValidBinding()) {
      this.thrownExceptions.add(binding);
    }
  }
 
  public void endVisit(MessageSend messageSend, BlockScope scope) {
    if (messageSend.binding != null) {
      this.endVisitMethodInvocation(messageSend.binding);
    }
    super.endVisit(messageSend, scope);
  }
 
  public void endVisit(AllocationExpression allocationExpression, BlockScope scope) {
    if (allocationExpression.binding != null) {
      this.endVisitMethodInvocation(allocationExpression.binding);
    }
    super.endVisit(allocationExpression, scope);
  }
 
  public void endVisit(ThrowStatement throwStatement, BlockScope scope) {
    this.acceptException((ReferenceBinding)throwStatement.exception.resolvedType);
    super.endVisit(throwStatement, scope);
  }
 
 
  private void endVisitMethodInvocation(MethodBinding methodBinding) {
    ReferenceBinding[] thrownExceptionBindings = methodBinding.thrownExceptions;
    int length = thrownExceptionBindings == null ? 0 : thrownExceptionBindings.length;
    for (int i = 0; i < length; i++) {
      this.acceptException(thrownExceptionBindings[i]);
    }
  }
 
  public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
    return this.visitType(typeDeclaration);
  }
 
  public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
    return this.visitType(memberTypeDeclaration);
  }
 
  public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
    return this.visitType(localTypeDeclaration);
  }
 
  private boolean visitType(TypeDeclaration typeDeclaration) {
    return false;
  }

  public boolean visit(TryStatement tryStatement, BlockScope scope) {
    this.exceptionsStack.push(this.thrownExceptions);
    SimpleSet exceptionSet = new SimpleSet();
    this.thrownExceptions = exceptionSet;
    tryStatement.tryBlock.traverse(this, scope);
   
    this.removeCaughtExceptions(tryStatement);

    this.thrownExceptions = (SimpleSet)this.exceptionsStack.pop();
   
    Object[] values = exceptionSet.values;
    for (int i = 0; i < values.length; i++) {
      if (values[i] != null) {
        this.thrownExceptions.add(values[i]);
      }
    }
   
    Block[] catchBlocks = tryStatement.catchBlocks;
    int length = catchBlocks == null ? 0 : catchBlocks.length;
    for (int i = 0; i < length; i++) {
      catchBlocks[i].traverse(this, scope);
    }
    return false;
  }
 
  private void removeCaughtExceptions(TryStatement tryStatement) {
    Argument[] catchArguments = tryStatement.catchArguments;
    int length = catchArguments == null ? 0 : catchArguments.length;
    for (int i = 0; i < length; i++) {
      TypeBinding exception = catchArguments[i].type.resolvedType;
      if (exception != null && exception.isValidBinding()) {
        this.removeCaughtException((ReferenceBinding)exception);
       
      }
    }
  }

  private void removeCaughtException(ReferenceBinding caughtException) {
    Object[] exceptions = this.thrownExceptions.values;
    for (int i = 0; i < exceptions.length; i++) {
      ReferenceBinding exception = (ReferenceBinding)exceptions[i];
      if (exception != null) {
        if (exception == caughtException || caughtException.isSuperclassOf(exception)) {
          this.thrownExceptions.remove(exception);
        }
      }
    }
  }
}
TOP

Related Classes of org.aspectj.org.eclipse.jdt.internal.codeassist.ThrownExceptionFinder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.