You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AstUtil.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.ajdt.internal.compiler.ast;
  13. import java.lang.reflect.Modifier;
  14. import java.util.ArrayList;
  15. import java.util.List;
  16. import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
  17. import org.aspectj.org.eclipse.jdt.internal.compiler.IAttribute;
  18. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
  19. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  20. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
  21. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
  22. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MessageSend;
  23. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
  24. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NameReference;
  25. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
  26. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
  27. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
  28. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
  29. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Statement;
  30. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  31. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeParameter;
  32. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
  33. import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
  34. import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.CodeStream;
  35. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.Constant;
  36. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding;
  37. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
  38. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
  39. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
  40. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
  41. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
  42. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
  43. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  44. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeIds;
  45. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
  46. import org.aspectj.weaver.AjAttribute;
  47. import org.aspectj.weaver.patterns.WildTypePattern;
  48. public class AstUtil {
  49. private AstUtil() {
  50. }
  51. public static void addMethodBinding(SourceTypeBinding sourceType, MethodBinding method) {
  52. int len = sourceType.methods.length;
  53. MethodBinding[] temp = new MethodBinding[len + 1];
  54. System.arraycopy(sourceType.methods, 0, temp, 0, len);
  55. temp[len] = method;
  56. sourceType.methods = temp;
  57. }
  58. public static void addMethodDeclaration(TypeDeclaration typeDec, AbstractMethodDeclaration dec) {
  59. AbstractMethodDeclaration[] methods = typeDec.methods;
  60. int len = methods.length;
  61. AbstractMethodDeclaration[] newMethods = new AbstractMethodDeclaration[len + 1];
  62. System.arraycopy(methods, 0, newMethods, 0, len);
  63. newMethods[len] = dec;
  64. typeDec.methods = newMethods;
  65. }
  66. public static Argument makeFinalArgument(char[] name, TypeBinding typeBinding) {
  67. long pos = 0; // XXX encode start and end location
  68. LocalVariableBinding binding = new LocalVariableBinding(name, typeBinding, Modifier.FINAL, true);
  69. Argument ret = new Argument(name, pos, makeTypeReference(typeBinding), Modifier.FINAL);
  70. ret.binding = binding;
  71. return ret;
  72. }
  73. public static TypeReference makeTypeReference(TypeBinding binding) {
  74. // ??? does this work for primitives
  75. QualifiedTypeReference ref = new QualifiedTypeReference(new char[][] { binding.sourceName() }, new long[] { 0 }); // ???
  76. ref.resolvedType = binding;
  77. ref.constant = Constant.NotAConstant;
  78. return ref;
  79. }
  80. public static NameReference makeNameReference(TypeBinding binding) {
  81. char[][] name = new char[][] { binding.sourceName() };
  82. long[] dummyPositions = new long[name.length];
  83. QualifiedNameReference ref = new QualifiedNameReference(name, dummyPositions, 0, 0);
  84. ref.binding = binding;
  85. ref.constant = Constant.NotAConstant;
  86. return ref;
  87. }
  88. public static ReturnStatement makeReturnStatement(Expression expr) {
  89. return new ReturnStatement(expr, 0, 0);
  90. }
  91. public static MethodDeclaration makeMethodDeclaration(MethodBinding binding) {
  92. MethodDeclaration ret = new MethodDeclaration(null);
  93. ret.binding = binding;
  94. int nargs = binding.parameters.length;
  95. ret.arguments = new Argument[nargs];
  96. for (int i = 0; i < nargs; i++) {
  97. ret.arguments[i] = makeFinalArgument(("arg" + i).toCharArray(), binding.parameters[i]);
  98. }
  99. return ret;
  100. }
  101. public static void setStatements(MethodDeclaration ret, List statements) {
  102. ret.statements = (Statement[]) statements.toArray(new Statement[0]);
  103. }
  104. public static SingleNameReference makeLocalVariableReference(LocalVariableBinding binding) {
  105. SingleNameReference ret = new SingleNameReference(binding.name, 0);
  106. ret.binding = binding;
  107. // ret.codegenBinding = binding;
  108. ret.constant = Constant.NotAConstant;
  109. ret.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
  110. ret.bits |= Binding.VARIABLE;
  111. return ret;
  112. }
  113. public static SingleNameReference makeResolvedLocalVariableReference(LocalVariableBinding binding) {
  114. SingleNameReference ret = new SingleNameReference(binding.name, 0);
  115. ret.binding = binding;
  116. // ret.codegenBinding = binding;
  117. ret.constant = Constant.NotAConstant;
  118. ret.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
  119. ret.bits |= Binding.LOCAL;
  120. return ret;
  121. }
  122. public static int makePublic(int modifiers) {
  123. return makePackageVisible(modifiers) | ClassFileConstants.AccPublic;
  124. }
  125. public static int makePackageVisible(int modifiers) {
  126. modifiers &= ~(ClassFileConstants.AccPublic | ClassFileConstants.AccPrivate | ClassFileConstants.AccProtected);
  127. return modifiers;
  128. }
  129. public static CompilationUnitScope getCompilationUnitScope(Scope scope) {
  130. if (scope instanceof CompilationUnitScope) {
  131. return (CompilationUnitScope) scope;
  132. }
  133. return getCompilationUnitScope(scope.parent);
  134. }
  135. public static void generateParameterLoads(TypeBinding[] parameters, CodeStream codeStream) {
  136. int paramIndex = 0;
  137. int varIndex = 0;
  138. while (paramIndex < parameters.length) {
  139. TypeBinding param = parameters[paramIndex++];
  140. codeStream.load(param, varIndex);
  141. varIndex += slotsNeeded(param);
  142. }
  143. }
  144. public static void generateParameterLoads(TypeBinding[] parameters, CodeStream codeStream, int offset) {
  145. int paramIndex = 0;
  146. int varIndex = offset;
  147. while (paramIndex < parameters.length) {
  148. TypeBinding param = parameters[paramIndex++];
  149. codeStream.load(param, varIndex);
  150. varIndex += slotsNeeded(param);
  151. }
  152. }
  153. public static void generateReturn(TypeBinding returnType, CodeStream codeStream) {
  154. if (returnType.id == TypeIds.T_void) {
  155. codeStream.return_();
  156. } else if (returnType.isBaseType()) {
  157. switch (returnType.id) {
  158. case TypeIds.T_boolean:
  159. case TypeIds.T_int:
  160. case TypeIds.T_byte:
  161. case TypeIds.T_short:
  162. case TypeIds.T_char:
  163. codeStream.ireturn();
  164. break;
  165. case TypeIds.T_float:
  166. codeStream.freturn();
  167. break;
  168. case TypeIds.T_long:
  169. codeStream.lreturn();
  170. break;
  171. case TypeIds.T_double:
  172. codeStream.dreturn();
  173. break;
  174. default:
  175. throw new RuntimeException("huh");
  176. }
  177. } else {
  178. codeStream.areturn();
  179. }
  180. }
  181. // XXX this could be inconsistent for wierd case, i.e. a class named "java_lang_String"
  182. public static char[] makeMangledName(ReferenceBinding type) {
  183. return CharOperation.concatWith(type.compoundName, '_');
  184. }
  185. public static final char[] PREFIX = "ajc".toCharArray();
  186. // XXX not efficient
  187. public static char[] makeAjcMangledName(char[] kind, ReferenceBinding type, char[] name) {
  188. return CharOperation.concat(CharOperation.concat(PREFIX, new char[] { '$' }, kind), '$', makeMangledName(type), '$', name);
  189. }
  190. public static char[] makeAjcMangledName(char[] kind, char[] p, char[] name) {
  191. return CharOperation.concat(CharOperation.concat(PREFIX, new char[] { '$' }, kind), '$', p, '$', name);
  192. }
  193. public static List getAjSyntheticAttribute() {
  194. List<IAttribute> ret = new ArrayList<>(1);
  195. ret.add(new EclipseAttributeAdapter(new AjAttribute.AjSynthetic()));
  196. return ret;
  197. }
  198. public static long makeLongPos(int start, int end) {
  199. return (long) end | ((long) start << 32);
  200. }
  201. public static char[][] getCompoundName(String string) {
  202. return WildTypePattern.splitNames(string, true);
  203. }
  204. public static TypeBinding[] insert(TypeBinding first, TypeBinding[] rest) {
  205. if (rest == null) {
  206. return new TypeBinding[] { first };
  207. }
  208. int len = rest.length;
  209. TypeBinding[] ret = new TypeBinding[len + 1];
  210. ret[0] = first;
  211. System.arraycopy(rest, 0, ret, 1, len);
  212. return ret;
  213. }
  214. public static Argument[] insert(Argument first, Argument[] rest) {
  215. if (rest == null) {
  216. return new Argument[] { first };
  217. }
  218. int len = rest.length;
  219. Argument[] ret = new Argument[len + 1];
  220. ret[0] = first;
  221. System.arraycopy(rest, 0, ret, 1, len);
  222. return ret;
  223. }
  224. public static TypeParameter[] insert(TypeParameter first, TypeParameter[] rest) {
  225. if (rest == null) {
  226. return new TypeParameter[]{first};
  227. }
  228. int len = rest.length;
  229. TypeParameter[] ret = new TypeParameter[len + 1];
  230. ret[0] = first;
  231. System.arraycopy(rest, 0, ret, 1, len);
  232. return ret;
  233. }
  234. public static TypeVariableBinding[] insert(TypeVariableBinding first, TypeVariableBinding[] rest) {
  235. if (rest == null) {
  236. return new TypeVariableBinding[]{first};
  237. }
  238. int len = rest.length;
  239. TypeVariableBinding[] ret = new TypeVariableBinding[len + 1];
  240. ret[0] = first;
  241. System.arraycopy(rest, 0, ret, 1, len);
  242. return ret;
  243. }
  244. public static TypeVariableBinding[] insert(TypeVariableBinding[] first, TypeVariableBinding[] rest) {
  245. if (rest == null) {
  246. TypeVariableBinding[] ret = new TypeVariableBinding[first.length];
  247. System.arraycopy(first, 0, ret, 0, first.length);
  248. return ret;
  249. }
  250. int len = rest.length;
  251. TypeVariableBinding[] ret = new TypeVariableBinding[first.length+len];
  252. System.arraycopy(first,0,ret,0,first.length);
  253. System.arraycopy(rest,0,ret,first.length,len);
  254. return ret;
  255. }
  256. public static Expression[] insert(Expression first, Expression[] rest) {
  257. if (rest == null) {
  258. return new Expression[] { first };
  259. }
  260. int len = rest.length;
  261. Expression[] ret = new Expression[len + 1];
  262. ret[0] = first;
  263. System.arraycopy(rest, 0, ret, 1, len);
  264. return ret;
  265. }
  266. public static Argument[] copyArguments(Argument[] inArgs) {
  267. // Lets do a proper copy
  268. if (inArgs == null)
  269. return new Argument[] {};
  270. Argument[] outArgs = new Argument[inArgs.length];
  271. for (int i = 0; i < inArgs.length; i++) {
  272. Argument argument = inArgs[i];
  273. outArgs[i] = new Argument(argument.name, 0, argument.type, argument.modifiers);
  274. }
  275. return outArgs;
  276. // if (inArgs == null) return new Argument[] {};
  277. // int len = inArgs.length;
  278. // Argument[] outArgs = new Argument[len];
  279. // //??? we're not sure whether or not copying these is okay
  280. // System.arraycopy(inArgs, 0, outArgs, 0, len);
  281. // return outArgs;
  282. }
  283. public static Statement[] remove(int i, Statement[] statements) {
  284. int len = statements.length;
  285. Statement[] ret = new Statement[len - 1];
  286. System.arraycopy(statements, 0, ret, 0, i);
  287. System.arraycopy(statements, i + 1, ret, i, len - i - 1);
  288. return ret;
  289. }
  290. public static int slotsNeeded(TypeBinding type) {
  291. if (type == TypeBinding.DOUBLE || type == TypeBinding.LONG)
  292. return 2;
  293. else
  294. return 1;
  295. }
  296. public static void replaceMethodBinding(MessageSend send, MethodBinding newBinding) {
  297. send.binding =/* send.codegenBinding =*/ newBinding;
  298. send.setActualReceiverType(newBinding.declaringClass);
  299. }
  300. }