Package org.eclipse.jdt.internal.core.util

Source Code of org.eclipse.jdt.internal.core.util.ExtendedAnnotation

/*******************************************************************************
* Copyright (c) 2012, 2013 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
*        Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
*                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
*                          Bug 409236 - [1.8][compiler] Type annotations on intersection cast types dropped by code generator
*                          Bug 409250 - [1.8][compiler] Various loose ends in 308 code generation
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;

import org.eclipse.jdt.core.util.ClassFormatException;
import org.eclipse.jdt.core.util.IAnnotationComponent;
import org.eclipse.jdt.core.util.IConstantPool;
import org.eclipse.jdt.core.util.IConstantPoolConstant;
import org.eclipse.jdt.core.util.IConstantPoolEntry;
import org.eclipse.jdt.core.util.IExtendedAnnotation;
import org.eclipse.jdt.core.util.IExtendedAnnotationConstants;
import org.eclipse.jdt.core.util.ILocalVariableReferenceInfo;

/* http://types.cs.washington.edu/jsr308/specification/java-annotation-design.pdf
type_annotation {
   // New fields in JSR 308:
   u1 target_type; // the type of the targeted program element, see Section 3.2
   union {
     type_parameter_target;
     supertype_target;
     type_parameter_bound_target;
     empty_target;
     method_formal_parameter_target;
     throws_target;
     localvar_target;
     catch_target;
     offset_target;
     type_argument_target;
     method_reference_target;
   } target_info; // identifies the targeted program element, see Section 3.3
   type_path target_path; // identifies targeted type in a compound type (array, generic, etc.), see Section 3.4
   // Original fields from "annotation" structure:
   u2 type_index;
   u2 num_element_value_pairs;
   {
     u2 element_name_index;
     element_value value;
   } element_value_pairs[num_element_value_pairs];
*/
/**
* @since 3.10
*/
public class ExtendedAnnotation extends ClassFileStruct implements IExtendedAnnotation {

  private static final IAnnotationComponent[] NO_ENTRIES = new IAnnotationComponent[0];
  private final static int[][] NO_TYPEPATH = new int[0][0];
  private final static ILocalVariableReferenceInfo[] NO_LOCAL_VARIABLE_TABLE_ENTRIES = new ILocalVariableReferenceInfo[0];

  private int targetType;
  private int annotationTypeIndex;
  private int[][] typePath;

  private int typeIndex;
  private char[] typeName;
  private int componentsNumber;
  private IAnnotationComponent[] components;
  private int readOffset;
  private int offset;
  private int typeParameterIndex;
  private int typeParameterBoundIndex;
  private int parameterIndex;
  private int exceptionTableIndex;
  private ILocalVariableReferenceInfo[] localVariableTable = NO_LOCAL_VARIABLE_TABLE_ENTRIES;
 
  /**
   * Constructor for ExtendedAnnotation, builds an annotation from the supplied bytestream.
   *
   * @param classFileBytes
   * @param constantPool
   * @param offset
   * @throws ClassFormatException
   */
  public ExtendedAnnotation(
      byte[] classFileBytes,
      IConstantPool constantPool,
      int offset) throws ClassFormatException {

    // Read target_type
    int index = u1At(classFileBytes,0,offset);
    this.targetType = index;
    this.readOffset = 1;
   
    readTargetInfo(index, classFileBytes, constantPool, offset);

    // Read type_path
    index = u1At(classFileBytes, this.readOffset, offset);
    this.readOffset++;
    int typePathEntryCount = index;
    if (typePathEntryCount == 0) {
      this.typePath = NO_TYPEPATH;
    } else {
      this.typePath = new int[typePathEntryCount][];
      for (int i = 0; i < typePathEntryCount; i++) {
        int[] typePathEntry = (this.typePath[i] = new int[2]);
        typePathEntry[0] = u1At(classFileBytes, this.readOffset++, offset);
        typePathEntry[1] = u1At(classFileBytes, this.readOffset++, offset);
      }
    }
   
    // Read annotation
    index = u2At(classFileBytes, this.readOffset, offset);
    this.typeIndex = index;
    this.readOffset+=2;
    if (index != 0) {
      IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
      if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
        throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
      }
      this.typeName = constantPoolEntry.getUtf8Value();
    } else {
      throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
    }
    final int length = u2At(classFileBytes, this.readOffset, offset);
    this.componentsNumber = length;
    this.readOffset+=2;
    if (length != 0) {
      this.components = new IAnnotationComponent[length];
      for (int i = 0; i < length; i++) {
        AnnotationComponent component = new AnnotationComponent(classFileBytes, constantPool, offset + this.readOffset);
        this.components[i] = component;
        this.readOffset += component.sizeInBytes();
      }
    } else {
      this.components = NO_ENTRIES;
    }
    if (this.annotationTypeIndex == 0xFFFF) {
      this.annotationTypeIndex = -1;
    }
  }
 
  private void readTargetInfo(
      int localTargetType,
      byte[] classFileBytes,
      IConstantPool constantPool,
      int localOffset) throws ClassFormatException {
    switch(localTargetType) {
      case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER :
      case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER :
        this.typeParameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
        this.readOffset++;
        break;

      case IExtendedAnnotationConstants.CLASS_EXTENDS :
        this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
        this.readOffset+=2;
        break;

      case IExtendedAnnotationConstants.CLASS_TYPE_PARAMETER_BOUND :
      case IExtendedAnnotationConstants.METHOD_TYPE_PARAMETER_BOUND :
        this.typeParameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
        this.readOffset++;
        this.typeParameterBoundIndex = u1At(classFileBytes, this.readOffset, localOffset);
        this.readOffset++;
        break;
       
      case IExtendedAnnotationConstants.FIELD :
      case IExtendedAnnotationConstants.METHOD_RETURN :
      case IExtendedAnnotationConstants.METHOD_RECEIVER :
        // nothing to do, target_info is empty_target
        break;
       
      case IExtendedAnnotationConstants.METHOD_FORMAL_PARAMETER :
        this.parameterIndex = u1At(classFileBytes, this.readOffset, localOffset);
        this.readOffset++;
        break;
       
      case IExtendedAnnotationConstants.THROWS :
        this.annotationTypeIndex = u2At(classFileBytes, this.readOffset, localOffset);
        this.readOffset+=2;
        break;

       
      case IExtendedAnnotationConstants.LOCAL_VARIABLE :
      case IExtendedAnnotationConstants.RESOURCE_VARIABLE :
        int tableLength = u2At(classFileBytes, this.readOffset, localOffset);
        this.readOffset += 2;
        this.localVariableTable = new LocalVariableReferenceInfo[tableLength];
        for (int i = 0; i < tableLength; i++) {
          this.localVariableTable[i] = new LocalVariableReferenceInfo(classFileBytes, constantPool, this.readOffset + localOffset);
          this.readOffset += 6;
        }
        break;

      case IExtendedAnnotationConstants.EXCEPTION_PARAMETER :
        this.exceptionTableIndex = u2At(classFileBytes, this.readOffset, localOffset);
        this.readOffset += 2;
        break;

      case IExtendedAnnotationConstants.NEW :
      case IExtendedAnnotationConstants.INSTANCEOF :
      case IExtendedAnnotationConstants.METHOD_REFERENCE :
      case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE :
        this.offset = u2At(classFileBytes, this.readOffset, localOffset);
        this.readOffset += 2;
        break

      case IExtendedAnnotationConstants.CAST :
        this.offset = u2At(classFileBytes, this.readOffset, localOffset);
        this.readOffset += 2;
        // read type_argument_index
        this.annotationTypeIndex = u1At(classFileBytes, this.readOffset, localOffset);
        this.readOffset++;
        break;

      case IExtendedAnnotationConstants.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT :
      case IExtendedAnnotationConstants.METHOD_INVOCATION_TYPE_ARGUMENT :
      case IExtendedAnnotationConstants.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT :
      case IExtendedAnnotationConstants.METHOD_REFERENCE_TYPE_ARGUMENT :
        this.offset = u2At(classFileBytes, this.readOffset, localOffset);
        this.readOffset += 2;
        // read type_argument_index
        this.annotationTypeIndex = u1At(classFileBytes, this.readOffset, localOffset);
        this.readOffset++;
        break;
    }
  }

  /* (non-Javadoc)
   * @see org.eclipse.jdt.core.util.IAnnotation#getTypeIndex()
   */
  public int getTypeIndex() {
    return this.typeIndex;
  }
  /* (non-Javadoc)
   * @see org.eclipse.jdt.core.util.IAnnotation#getComponentsNumber()
   */
  public int getComponentsNumber() {
    return this.componentsNumber;
  }
  /* (non-Javadoc)
   * @see org.eclipse.jdt.core.util.IAnnotation#getComponents()
   */
  public IAnnotationComponent[] getComponents() {
    return this.components;
  }

  int sizeInBytes() {
    return this.readOffset;
  }
  /* (non-Javadoc)
   * @see org.eclipse.jdt.core.util.IAnnotation#getTypeName()
   */
  public char[] getTypeName() {
    return this.typeName;
  }

  public int getTargetType() {
    return this.targetType;
  }
 
  public int getExceptionTableIndex() {
    return this.exceptionTableIndex;
  }

  public int getOffset() {
    return this.offset;
  }

  public int getLocalVariableRefenceInfoLength() {
    return this.localVariableTable.length;
  }

  public ILocalVariableReferenceInfo[] getLocalVariableTable() {
    return this.localVariableTable;
  }

  public int getParameterIndex() {
    return this.parameterIndex;
  }

  public int getTypeParameterIndex() {
    return this.typeParameterIndex;
  }

  public int getTypeParameterBoundIndex() {
    return this.typeParameterBoundIndex;
  }

  public int[][] getTypePath() {
    return this.typePath;
  }

  public int getAnnotationTypeIndex() {
    return this.annotationTypeIndex;
  }
}
TOP

Related Classes of org.eclipse.jdt.internal.core.util.ExtendedAnnotation

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.