1 /*******************************************************************************
2  * Copyright (c) 2016 Google, Inc and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *   Stefan Xenos (Google) - Initial implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.core.nd.java;
15 
16 import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
17 import org.eclipse.jdt.internal.core.nd.IDestructable;
18 import org.eclipse.jdt.internal.core.nd.Nd;
19 import org.eclipse.jdt.internal.core.nd.db.Database;
20 import org.eclipse.jdt.internal.core.nd.field.FieldByte;
21 import org.eclipse.jdt.internal.core.nd.field.FieldPointer;
22 import org.eclipse.jdt.internal.core.nd.field.StructDef;
23 
24 public class NdTypeAnnotation extends NdAnnotation implements IDestructable {
25 	public static final FieldByte TARGET_TYPE;
26 	public static final FieldByte TARGET_ARG0;
27 	public static final FieldByte TARGET_ARG1;
28 	public static final FieldByte PATH_LENGTH;
29 	public static final FieldPointer PATH;
30 
31 	@SuppressWarnings("hiding")
32 	public static final StructDef<NdTypeAnnotation> type;
33 
34 	static {
35 		type = StructDef.create(NdTypeAnnotation.class, NdAnnotation.type);
36 		TARGET_TYPE = type.addByte();
37 		TARGET_ARG0 = type.addByte();
38 		TARGET_ARG1 = type.addByte();
39 		PATH_LENGTH = type.addByte();
40 		PATH = type.addPointer();
type.done()41 		type.done();
42 	}
43 
44 	private static final byte[] NO_TYPE_PATH = new byte[0];
45 
NdTypeAnnotation(Nd nd, long address)46 	public NdTypeAnnotation(Nd nd, long address) {
47 		super(nd, address);
48 	}
49 
setPath(byte[] path)50 	public void setPath(byte[] path) {
51 		freePath();
52 		PATH_LENGTH.put(this.nd, this.address, (byte) path.length);
53 		if (path.length > 0) {
54 			long pathArray = this.nd.getDB().malloc(path.length, Database.POOL_MISC);
55 			PATH.put(this.nd, this.address, pathArray);
56 			this.nd.getDB().putBytes(pathArray, path, path.length);
57 		}
58 	}
59 
setTargetInfo(int arg)60 	public void setTargetInfo(int arg) {
61 		TARGET_ARG0.put(getNd(), this.address, (byte)((arg >> 8) & 0xff));
62 		TARGET_ARG1.put(getNd(), this.address, (byte)(arg & 0xff));
63 	}
64 
getTargetInfoArg0()65 	public byte getTargetInfoArg0() {
66 		return TARGET_ARG0.get(getNd(), this.address);
67 	}
68 
getTargetInfoArg1()69 	public byte getTargetInfoArg1() {
70 		return TARGET_ARG1.get(getNd(), this.address);
71 	}
72 
getTarget()73 	public int getTarget() {
74 		int arg0 = TARGET_ARG0.get(getNd(), this.address) & 0xff;
75 		int arg1 = TARGET_ARG1.get(getNd(), this.address) & 0xff;
76 		int result = (arg0 << 8) | arg1;
77 		return result;
78 	}
79 
setTargetInfo(byte arg0, byte arg1)80 	public void setTargetInfo(byte arg0, byte arg1) {
81 		TARGET_ARG0.put(getNd(), this.address, arg0);
82 		TARGET_ARG1.put(getNd(), this.address, arg1);
83 	}
84 
85 	/**
86 	 * @param targetType one of the constants from {@link AnnotationTargetTypeConstants}
87 	 */
setTargetType(int targetType)88 	public void setTargetType(int targetType) {
89 		TARGET_TYPE.put(getNd(), this.address, (byte)targetType);
90 	}
91 
92 	/**
93 	 * @return one of the constants from {@link AnnotationTargetTypeConstants}
94 	 */
getTargetType()95 	public int getTargetType() {
96 		return TARGET_TYPE.get(getNd(), this.address);
97 	}
98 
getTypePath()99 	public byte[] getTypePath() {
100 		long pathPointer = PATH.get(getNd(), this.address);
101 		if (pathPointer == 0) {
102 			return NO_TYPE_PATH;
103 		}
104 		int pathLength = PATH_LENGTH.get(getNd(), this.address);
105 		byte[] result = new byte[pathLength];
106 		getNd().getDB().getBytes(pathPointer, result);
107 		return result;
108 	}
109 
110 	@Override
destruct()111 	public void destruct() {
112 		freePath();
113 	}
114 
freePath()115 	private void freePath() {
116 		long pathPointer = PATH.get(this.nd, this.address);
117 		this.nd.getDB().free(pathPointer, Database.POOL_MISC);
118 	}
119 }
120