Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

AllocationExpression.java 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*******************************************************************************
  2. * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Common Public License v0.5
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/cpl-v05.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. ******************************************************************************/
  11. package org.eclipse.jdt.internal.compiler.ast;
  12. import org.eclipse.jdt.internal.compiler.IAbstractSyntaxTreeVisitor;
  13. import org.eclipse.jdt.internal.compiler.codegen.*;
  14. import org.eclipse.jdt.internal.compiler.flow.*;
  15. import org.eclipse.jdt.internal.compiler.lookup.*;
  16. public class AllocationExpression
  17. extends Expression
  18. implements InvocationSite {
  19. public TypeReference type;
  20. public Expression[] arguments;
  21. public MethodBinding binding;
  22. MethodBinding syntheticAccessor;
  23. public AllocationExpression() {
  24. super();
  25. }
  26. public FlowInfo analyseCode(
  27. BlockScope currentScope,
  28. FlowContext flowContext,
  29. FlowInfo flowInfo) {
  30. // must verify that exceptions potentially thrown by this expression are caught in the method
  31. // process arguments
  32. if (arguments != null) {
  33. for (int i = 0, count = arguments.length; i < count; i++) {
  34. flowInfo =
  35. arguments[i]
  36. .analyseCode(currentScope, flowContext, flowInfo)
  37. .unconditionalInits();
  38. }
  39. }
  40. // record some dependency information for exception types
  41. ReferenceBinding[] thrownExceptions;
  42. if (((thrownExceptions = binding.thrownExceptions).length) != 0) {
  43. // check exception handling
  44. flowContext.checkExceptionHandlers(
  45. thrownExceptions,
  46. this,
  47. flowInfo,
  48. currentScope);
  49. }
  50. manageEnclosingInstanceAccessIfNecessary(currentScope);
  51. manageSyntheticAccessIfNecessary(currentScope);
  52. return flowInfo;
  53. }
  54. public Expression enclosingInstance() {
  55. return null;
  56. }
  57. public void generateCode(
  58. BlockScope currentScope,
  59. CodeStream codeStream,
  60. boolean valueRequired) {
  61. int pc = codeStream.position;
  62. ReferenceBinding allocatedType;
  63. if (syntheticAccessor != null) {
  64. allocatedType = syntheticAccessor.declaringClass;
  65. } else {
  66. allocatedType = binding.declaringClass;
  67. }
  68. codeStream.new_(allocatedType);
  69. if (valueRequired) {
  70. codeStream.dup();
  71. }
  72. // better highlight for allocation: display the type individually
  73. codeStream.recordPositionsFrom(pc, type.sourceStart);
  74. // handling innerclass instance allocation
  75. if (allocatedType.isNestedType()) {
  76. codeStream.generateSyntheticArgumentValues(
  77. currentScope,
  78. allocatedType,
  79. enclosingInstance(),
  80. this);
  81. }
  82. // generate the arguments for constructor
  83. if (arguments != null) {
  84. for (int i = 0, count = arguments.length; i < count; i++) {
  85. arguments[i].generateCode(currentScope, codeStream, true);
  86. }
  87. }
  88. // invoke constructor
  89. if (syntheticAccessor == null) {
  90. codeStream.invokespecial(binding);
  91. } else {
  92. // synthetic accessor got some extra arguments appended to its signature, which need values
  93. for (int i = 0,
  94. max = syntheticAccessor.parameters.length - binding.parameters.length;
  95. i < max;
  96. i++) {
  97. codeStream.aconst_null();
  98. }
  99. codeStream.invokespecial(syntheticAccessor);
  100. }
  101. codeStream.recordPositionsFrom(pc, this.sourceStart);
  102. }
  103. public boolean isSuperAccess() {
  104. return false;
  105. }
  106. public boolean isTypeAccess() {
  107. return true;
  108. }
  109. /* Inner emulation consists in either recording a dependency
  110. * link only, or performing one level of propagation.
  111. *
  112. * Dependency mechanism is used whenever dealing with source target
  113. * types, since by the time we reach them, we might not yet know their
  114. * exact need.
  115. */
  116. public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope) {
  117. ReferenceBinding allocatedType;
  118. // perform some emulation work in case there is some and we are inside a local type only
  119. if ((allocatedType = binding.declaringClass).isNestedType()
  120. && currentScope.enclosingSourceType().isLocalType()) {
  121. if (allocatedType.isLocalType()) {
  122. ((LocalTypeBinding) allocatedType).addInnerEmulationDependent(
  123. currentScope,
  124. false,
  125. false);
  126. // request cascade of accesses
  127. } else {
  128. // locally propagate, since we already now the desired shape for sure
  129. currentScope.propagateInnerEmulation(allocatedType, false, false);
  130. // request cascade of accesses
  131. }
  132. }
  133. }
  134. public void manageSyntheticAccessIfNecessary(BlockScope currentScope) {
  135. if (binding.alwaysNeedsAccessMethod()) {
  136. syntheticAccessor = binding.getAccessMethod(true);
  137. return;
  138. }
  139. if (binding.isPrivate()
  140. && (currentScope.enclosingSourceType() != binding.declaringClass)) {
  141. if (currentScope
  142. .environment()
  143. .options
  144. .isPrivateConstructorAccessChangingVisibility) {
  145. binding.tagForClearingPrivateModifier();
  146. // constructor will not be dumped as private, no emulation required thus
  147. } else {
  148. syntheticAccessor =
  149. ((SourceTypeBinding) binding.declaringClass).addSyntheticMethod(binding);
  150. currentScope.problemReporter().needToEmulateMethodAccess(binding, this);
  151. }
  152. }
  153. }
  154. public TypeBinding resolveType(BlockScope scope) {
  155. // Propagate the type checking to the arguments, and check if the constructor is defined.
  156. constant = NotAConstant;
  157. TypeBinding typeBinding = type.resolveType(scope);
  158. // will check for null after args are resolved
  159. // buffering the arguments' types
  160. TypeBinding[] argumentTypes = NoParameters;
  161. if (arguments != null) {
  162. boolean argHasError = false;
  163. int length = arguments.length;
  164. argumentTypes = new TypeBinding[length];
  165. for (int i = 0; i < length; i++)
  166. if ((argumentTypes[i] = arguments[i].resolveType(scope)) == null)
  167. argHasError = true;
  168. if (argHasError)
  169. return typeBinding;
  170. }
  171. if (typeBinding == null)
  172. return null;
  173. if (!typeBinding.canBeInstantiated()) {
  174. scope.problemReporter().cannotInstantiate(type, typeBinding);
  175. return typeBinding;
  176. }
  177. ReferenceBinding allocatedType = (ReferenceBinding) typeBinding;
  178. if (!(binding = scope.getConstructor(allocatedType, argumentTypes, this))
  179. .isValidBinding()) {
  180. if (binding.declaringClass == null)
  181. binding.declaringClass = allocatedType;
  182. scope.problemReporter().invalidConstructor(this, binding);
  183. return typeBinding;
  184. }
  185. if (isMethodUseDeprecated(binding, scope))
  186. scope.problemReporter().deprecatedMethod(binding, this);
  187. if (arguments != null)
  188. for (int i = 0; i < arguments.length; i++)
  189. arguments[i].implicitWidening(binding.parameters[i], argumentTypes[i]);
  190. return allocatedType;
  191. }
  192. public void setActualReceiverType(ReferenceBinding receiverType) {
  193. // ignored
  194. }
  195. public void setDepth(int i) {
  196. // ignored
  197. }
  198. public void setFieldIndex(int i) {
  199. // ignored
  200. }
  201. public String toStringExpression() {
  202. String s = "new " + type.toString(0); //$NON-NLS-1$
  203. if (arguments == null)
  204. s = s + "()"; //$NON-NLS-1$
  205. else {
  206. s = s + "("; //$NON-NLS-1$
  207. for (int i = 0; i < arguments.length; i++) {
  208. s = s + arguments[i].toStringExpression();
  209. if (i == (arguments.length - 1))
  210. s = s + ")"; //$NON-NLS-1$
  211. else
  212. s = s + ", "; //$NON-NLS-1$
  213. }
  214. }
  215. return s;
  216. }
  217. public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
  218. if (visitor.visit(this, scope)) {
  219. int argumentsLength;
  220. type.traverse(visitor, scope);
  221. if (arguments != null) {
  222. argumentsLength = arguments.length;
  223. for (int i = 0; i < argumentsLength; i++)
  224. arguments[i].traverse(visitor, scope);
  225. }
  226. }
  227. visitor.endVisit(this, scope);
  228. }
  229. }