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 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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 Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  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.weaver.AjAttribute;
  17. import org.aspectj.weaver.patterns.WildTypePattern;
  18. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  19. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
  20. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
  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.TypeReference;
  32. import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.CodeStream;
  33. import org.aspectj.org.eclipse.jdt.internal.compiler.env.IConstants;
  34. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.Constant;
  35. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
  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.core.compiler.CharOperation;
  46. public class AstUtil {
  47. private AstUtil() {}
  48. public static void addMethodBinding(SourceTypeBinding sourceType, MethodBinding method) {
  49. int len = sourceType.methods.length;
  50. MethodBinding[] temp = new MethodBinding[len + 1];
  51. System.arraycopy(sourceType.methods, 0, temp, 0, len);
  52. temp[len] = method;
  53. sourceType.methods = temp;
  54. }
  55. public static void addMethodDeclaration(TypeDeclaration typeDec, AbstractMethodDeclaration dec) {
  56. AbstractMethodDeclaration[] methods = typeDec.methods;
  57. int len = methods.length;
  58. AbstractMethodDeclaration[] newMethods = new AbstractMethodDeclaration[len+1];
  59. System.arraycopy(methods, 0, newMethods, 0, len);
  60. newMethods[len] = dec;
  61. typeDec.methods = newMethods;
  62. }
  63. public static Argument makeFinalArgument(char[] name, TypeBinding typeBinding) {
  64. long pos = 0; //XXX encode start and end location
  65. LocalVariableBinding binding =
  66. new LocalVariableBinding(name, typeBinding, Modifier.FINAL, true);
  67. Argument ret = new Argument(name, pos, makeTypeReference(typeBinding), Modifier.FINAL);
  68. ret.binding = binding;
  69. return ret;
  70. }
  71. public static TypeReference makeTypeReference(TypeBinding binding) {
  72. // ??? does this work for primitives
  73. QualifiedTypeReference ref =
  74. new QualifiedTypeReference(new char[][] {binding.sourceName()}, new long[] {0}); //???
  75. ref.resolvedType = binding;
  76. ref.constant = Constant.NotAConstant;
  77. return ref;
  78. }
  79. public static NameReference makeNameReference(TypeBinding binding) {
  80. char[][] name = new char[][] {binding.sourceName()};
  81. long[] dummyPositions = new long[name.length];
  82. QualifiedNameReference ref =
  83. new QualifiedNameReference(name, dummyPositions, 0, 0);
  84. ref.binding = binding; ref.constant = Constant.NotAConstant;
  85. return ref;
  86. }
  87. public static ReturnStatement makeReturnStatement(Expression expr) {
  88. return new ReturnStatement(expr, 0, 0);
  89. }
  90. public static MethodDeclaration makeMethodDeclaration(
  91. MethodBinding binding)
  92. {
  93. MethodDeclaration ret = new MethodDeclaration(null);
  94. ret.binding = binding;
  95. int nargs = binding.parameters.length;
  96. ret.arguments = new Argument[nargs];
  97. for (int i=0; i < nargs; i++) {
  98. ret.arguments[i] = makeFinalArgument(("arg"+i).toCharArray(),
  99. binding.parameters[i]);
  100. }
  101. return ret;
  102. }
  103. public static void setStatements(
  104. MethodDeclaration ret, List statements)
  105. {
  106. ret.statements =
  107. (Statement[])statements.toArray(new Statement[statements.size()]);
  108. }
  109. public static SingleNameReference makeLocalVariableReference(
  110. LocalVariableBinding binding)
  111. {
  112. SingleNameReference ret = new SingleNameReference(binding.name, 0);
  113. ret.binding = binding;
  114. ret.codegenBinding = binding;
  115. ret.constant = ASTNode.NotAConstant;
  116. ret.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
  117. ret.bits |= Binding.VARIABLE;
  118. return ret;
  119. }
  120. public static SingleNameReference makeResolvedLocalVariableReference(
  121. LocalVariableBinding binding)
  122. {
  123. SingleNameReference ret = new SingleNameReference(binding.name, 0);
  124. ret.binding = binding;
  125. ret.codegenBinding = binding;
  126. ret.constant = ASTNode.NotAConstant;
  127. ret.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
  128. ret.bits |= Binding.LOCAL;
  129. return ret;
  130. }
  131. public static int makePublic(int modifiers) {
  132. return makePackageVisible(modifiers) | IConstants.AccPublic;
  133. }
  134. public static int makePackageVisible(int modifiers) {
  135. modifiers &= ~(IConstants.AccPublic | IConstants.AccPrivate | IConstants.AccProtected);
  136. return modifiers;
  137. }
  138. public static CompilationUnitScope getCompilationUnitScope(Scope scope) {
  139. if (scope instanceof CompilationUnitScope) {
  140. return (CompilationUnitScope)scope;
  141. }
  142. return getCompilationUnitScope(scope.parent);
  143. }
  144. public static void generateParameterLoads(TypeBinding[] parameters, CodeStream codeStream) {
  145. int paramIndex = 0;
  146. int varIndex = 0;
  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 TypeBinding.T_boolean :
  159. case TypeBinding.T_int :
  160. case TypeBinding.T_byte :
  161. case TypeBinding.T_short :
  162. case TypeBinding.T_char :
  163. codeStream.ireturn();
  164. break;
  165. case TypeBinding.T_float :
  166. codeStream.freturn();
  167. break;
  168. case TypeBinding.T_long :
  169. codeStream.lreturn();
  170. break;
  171. case TypeBinding.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(
  189. CharOperation.concat(PREFIX, new char[] {'$'}, kind), '$', makeMangledName(type), '$', name);
  190. }
  191. public static char[] makeAjcMangledName(char[] kind, char[] p, char[] name) {
  192. return CharOperation.concat(
  193. CharOperation.concat(PREFIX, new char[] {'$'}, kind), '$', p, '$', name);
  194. }
  195. public static List getAjSyntheticAttribute() {
  196. ArrayList ret = new ArrayList(1);
  197. ret.add(new EclipseAttributeAdapter(new AjAttribute.AjSynthetic()));
  198. return ret;
  199. }
  200. public static long makeLongPos(int start, int end) {
  201. return (long)end | ((long)start << 32);
  202. }
  203. public static char[][] getCompoundName(String string) {
  204. return WildTypePattern.splitNames(string);
  205. }
  206. public static TypeBinding[] insert(
  207. TypeBinding first,
  208. TypeBinding[] rest) {
  209. if (rest == null) {
  210. return new TypeBinding[] {first};
  211. }
  212. int len = rest.length;
  213. TypeBinding[] ret = new TypeBinding[len+1];
  214. ret[0] = first;
  215. System.arraycopy(rest, 0, ret, 1, len);
  216. return ret;
  217. }
  218. public static Argument[] insert(
  219. Argument first,
  220. Argument[] rest) {
  221. if (rest == null) {
  222. return new Argument[] {first};
  223. }
  224. int len = rest.length;
  225. Argument[] ret = new Argument[len+1];
  226. ret[0] = first;
  227. System.arraycopy(rest, 0, ret, 1, len);
  228. return ret;
  229. }
  230. public static Argument[] copyArguments(Argument[] inArgs) {
  231. if (inArgs == null) return new Argument[] {};
  232. int len = inArgs.length;
  233. Argument[] outArgs = new Argument[len];
  234. //??? we're not sure whether or not copying these is okay
  235. System.arraycopy(inArgs, 0, outArgs, 0, len);
  236. return outArgs;
  237. }
  238. public static Statement[] remove(int i, Statement[] statements) {
  239. int len = statements.length;
  240. Statement[] ret = new Statement[len-1];
  241. System.arraycopy(statements, 0, ret, 0, i);
  242. System.arraycopy(statements, i+1, ret, i, len-i-1);
  243. return ret;
  244. }
  245. public static int slotsNeeded(TypeBinding type) {
  246. if (type == BaseTypes.DoubleBinding || type == BaseTypes.LongBinding) return 2;
  247. else return 1;
  248. }
  249. public static void replaceMethodBinding(MessageSend send, MethodBinding newBinding) {
  250. send.binding = send.codegenBinding = newBinding;
  251. send.setActualReceiverType(newBinding.declaringClass);
  252. }
  253. }