blob: 0b8d7d4ed3b1ad730506c71ee3dfc1014f6cd996 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015, 2016 Google, Inc 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:
* Stefan Xenos (Google) - Initial implementation
*******************************************************************************/
package org.eclipse.jdt.internal.core.nd.java.model;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;
public class TypeAnnotationBuilder implements ITypeAnnotationBuilder {
TypeAnnotationBuilder parent;
int kind;
int index;
int length;
int target;
int targetParameter;
int targetParameter2;
private TypeAnnotationBuilder(TypeAnnotationBuilder parent, int kind, int index,
int length, int nextTarget, int nextTargetParameter, int nextTargetParameter2) {
super();
this.parent = parent;
this.kind = kind;
this.index = index;
this.length = length;
this.target = nextTarget;
this.targetParameter = nextTargetParameter;
this.targetParameter2 = nextTargetParameter2;
}
public static TypeAnnotationBuilder create() {
return new TypeAnnotationBuilder(null, 0, 0, 0, -1, -1, -1);
}
private TypeAnnotationBuilder walk(int nextKind, int nextIndex) {
return new TypeAnnotationBuilder(this, nextKind, nextIndex, this.length+1, this.target, this.targetParameter, this.targetParameter2);
}
private TypeAnnotationBuilder toTarget(int newTarget) {
return new TypeAnnotationBuilder(this.parent, this.kind, this.index, this.length, newTarget, this.targetParameter, this.targetParameter2);
}
private TypeAnnotationBuilder toTarget(int newTarget, int parameter) {
return new TypeAnnotationBuilder(this.parent, this.kind, this.index, this.length, newTarget, parameter, this.targetParameter2);
}
private TypeAnnotationBuilder toTarget2(int parameter) {
return new TypeAnnotationBuilder(this.parent, this.kind, this.index, this.length, this.target, this.targetParameter, parameter);
}
@Override
public ITypeAnnotationBuilder toField() {
return toTarget(AnnotationTargetTypeConstants.FIELD);
}
@Override
public ITypeAnnotationBuilder toMethodReturn() {
return toTarget(AnnotationTargetTypeConstants.METHOD_RETURN);
}
@Override
public ITypeAnnotationBuilder toReceiver() {
return toTarget(AnnotationTargetTypeConstants.METHOD_RECEIVER);
}
@Override
public ITypeAnnotationBuilder toTypeParameter(boolean isClassTypeParameter, int rank) {
int targetType = isClassTypeParameter ? AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER
: AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER;
return toTarget(targetType, rank);
}
@Override
public ITypeAnnotationBuilder toTypeParameterBounds(boolean isClassTypeParameter, int parameterRank) {
int targetType = isClassTypeParameter ?
AnnotationTargetTypeConstants.CLASS_TYPE_PARAMETER_BOUND : AnnotationTargetTypeConstants.METHOD_TYPE_PARAMETER_BOUND;
return toTarget(targetType, parameterRank);
}
@Override
public ITypeAnnotationBuilder toTypeBound(short boundIndex) {
return toTarget2(boundIndex);
}
@Override
public ITypeAnnotationBuilder toSupertype(short superTypeIndex) {
return toTarget(AnnotationTargetTypeConstants.CLASS_EXTENDS, superTypeIndex);
}
@Override
public ITypeAnnotationBuilder toMethodParameter(short parameterIndex) {
return toTarget(AnnotationTargetTypeConstants.METHOD_FORMAL_PARAMETER, parameterIndex);
}
@Override
public ITypeAnnotationBuilder toThrows(int rank) {
return toTarget(AnnotationTargetTypeConstants.THROWS, rank);
}
@Override
public ITypeAnnotationBuilder toTypeArgument(int rank) {
return walk(AnnotationTargetTypeConstants.TYPE_ARGUMENT, rank);
}
@Override
public ITypeAnnotationBuilder toWildcardBound() {
return walk(AnnotationTargetTypeConstants.WILDCARD_BOUND, 0);
}
@Override
public ITypeAnnotationBuilder toNextArrayDimension() {
return walk(AnnotationTargetTypeConstants.NEXT_ARRAY_DIMENSION, 0);
}
@Override
public ITypeAnnotationBuilder toNextNestedType() {
return walk(AnnotationTargetTypeConstants.NEXT_NESTED_TYPE, 0);
}
@Override
public IBinaryTypeAnnotation build(IBinaryAnnotation annotation) {
return new IndexBinaryTypeAnnotation(this.target, this.targetParameter, this.targetParameter2, getTypePath(), annotation);
}
private int[] getTypePath() {
if (this.length == 0) {
return IBinaryTypeAnnotation.NO_TYPE_PATH;
}
int[] result = new int[this.length * 2];
TypeAnnotationBuilder next = this;
while (next != null && next.length > 0) {
int writeIdx = (next.length - 1) * 2;
result[writeIdx] = next.kind;
result[writeIdx + 1] = next.index;
next = next.parent;
}
return result;
}
}