1 11 package org.eclipse.jdt.internal.eval; 12 13 import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; 14 import org.eclipse.jdt.internal.compiler.ast.CastExpression; 15 import org.eclipse.jdt.internal.compiler.ast.Expression; 16 import org.eclipse.jdt.internal.compiler.codegen.CodeStream; 17 import org.eclipse.jdt.internal.compiler.flow.FlowInfo; 18 import org.eclipse.jdt.internal.compiler.impl.Constant; 19 import org.eclipse.jdt.internal.compiler.lookup.Binding; 20 import org.eclipse.jdt.internal.compiler.lookup.BlockScope; 21 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 22 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 23 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding; 24 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; 25 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 26 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 27 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 28 29 public class CodeSnippetAllocationExpression extends AllocationExpression implements ProblemReasons, EvaluationConstants { 30 EvaluationContext evaluationContext; 31 FieldBinding delegateThis; 32 35 public CodeSnippetAllocationExpression(EvaluationContext evaluationContext) { 36 this.evaluationContext = evaluationContext; 37 } 38 public void generateCode( 39 BlockScope currentScope, 40 CodeStream codeStream, 41 boolean valueRequired) { 42 43 int pc = codeStream.position; 44 ReferenceBinding allocatedType = this.codegenBinding.declaringClass; 45 46 if (this.codegenBinding.canBeSeenBy(allocatedType, this, currentScope)) { 47 codeStream.new_(allocatedType); 48 if (valueRequired) { 49 codeStream.dup(); 50 } 51 codeStream.recordPositionsFrom(pc, this.type.sourceStart); 53 54 if (allocatedType.isNestedType()) { 56 codeStream.generateSyntheticEnclosingInstanceValues( 57 currentScope, 58 allocatedType, 59 enclosingInstance(), 60 this); 61 } 62 if (this.arguments != null) { 64 for (int i = 0, count = this.arguments.length; i < count; i++) { 65 this.arguments[i].generateCode(currentScope, codeStream, true); 66 } 67 } 68 if (allocatedType.isNestedType()) { 70 codeStream.generateSyntheticOuterArgumentValues( 71 currentScope, 72 allocatedType, 73 this); 74 } 75 codeStream.invokespecial(this.codegenBinding); 77 } else { 78 codeStream.generateEmulationForConstructor(currentScope, this.codegenBinding); 80 if (this.arguments != null) { 82 int argsLength = this.arguments.length; 83 codeStream.generateInlinedValue(argsLength); 84 codeStream.newArray(currentScope.createArrayType(currentScope.getType(TypeConstants.JAVA_LANG_OBJECT, 3), 1)); 85 codeStream.dup(); 86 for (int i = 0; i < argsLength; i++) { 87 codeStream.generateInlinedValue(i); 88 this.arguments[i].generateCode(currentScope, codeStream, true); 89 TypeBinding parameterBinding = this.codegenBinding.parameters[i]; 90 if (parameterBinding.isBaseType() && parameterBinding != TypeBinding.NULL) { 91 codeStream.generateBoxingConversion(this.codegenBinding.parameters[i].id); 92 } 93 codeStream.aastore(); 94 if (i < argsLength - 1) { 95 codeStream.dup(); 96 } 97 } 98 } else { 99 codeStream.generateInlinedValue(0); 100 codeStream.newArray(currentScope.createArrayType(currentScope.getType(TypeConstants.JAVA_LANG_OBJECT, 3), 1)); 101 } 102 codeStream.invokeJavaLangReflectConstructorNewInstance(); 103 codeStream.checkcast(allocatedType); 104 } 105 codeStream.recordPositionsFrom(pc, this.sourceStart); 106 } 107 114 public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) { 115 } 117 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) { 118 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { 119 120 this.codegenBinding = this.binding.original(); 122 } 123 } 124 public TypeBinding resolveType(BlockScope scope) { 125 this.constant = Constant.NotAConstant; 127 this.resolvedType = this.type.resolveType(scope, true ); 129 boolean argsContainCast = false; 131 TypeBinding[] argumentTypes = Binding.NO_PARAMETERS; 132 if (this.arguments != null) { 133 boolean argHasError = false; 134 int length = this.arguments.length; 135 argumentTypes = new TypeBinding[length]; 136 for (int i = 0; i < length; i++) { 137 Expression argument = this.arguments[i]; 138 if (argument instanceof CastExpression) { 139 argument.bits |= DisableUnnecessaryCastCheck; argsContainCast = true; 141 } 142 if ((argumentTypes[i] = argument.resolveType(scope)) == null) { 143 argHasError = true; 144 } 145 } 146 if (argHasError) { 147 return this.resolvedType; 148 } 149 } 150 if (this.resolvedType == null) { 151 return null; 152 } 153 if (!this.resolvedType.canBeInstantiated()) { 154 scope.problemReporter().cannotInstantiate(this.type, this.resolvedType); 155 return this.resolvedType; 156 } 157 ReferenceBinding allocatedType = (ReferenceBinding) this.resolvedType; 158 if (!(this.binding = scope.getConstructor(allocatedType, argumentTypes, this)).isValidBinding()) { 159 if (this.binding instanceof ProblemMethodBinding 160 && ((ProblemMethodBinding) this.binding).problemId() == NotVisible) { 161 if (this.evaluationContext.declaringTypeName != null) { 162 this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this); 163 if (this.delegateThis == null) { 164 if (this.binding.declaringClass == null) { 165 this.binding.declaringClass = allocatedType; 166 } 167 scope.problemReporter().invalidConstructor(this, this.binding); 168 return this.resolvedType; 169 } 170 } else { 171 if (this.binding.declaringClass == null) { 172 this.binding.declaringClass = allocatedType; 173 } 174 scope.problemReporter().invalidConstructor(this, this.binding); 175 return this.resolvedType; 176 } 177 CodeSnippetScope localScope = new CodeSnippetScope(scope); 178 MethodBinding privateBinding = localScope.getConstructor((ReferenceBinding)this.delegateThis.type, argumentTypes, this); 179 if (!privateBinding.isValidBinding()) { 180 if (this.binding.declaringClass == null) { 181 this.binding.declaringClass = allocatedType; 182 } 183 scope.problemReporter().invalidConstructor(this, this.binding); 184 return this.resolvedType; 185 } else { 186 this.binding = privateBinding; 187 } 188 } else { 189 if (this.binding.declaringClass == null) { 190 this.binding.declaringClass = allocatedType; 191 } 192 scope.problemReporter().invalidConstructor(this, this.binding); 193 return this.resolvedType; 194 } 195 } 196 if (isMethodUseDeprecated(this.binding, scope, true)) { 197 scope.problemReporter().deprecatedMethod(this.binding, this); 198 } 199 if (arguments != null) { 200 for (int i = 0; i < arguments.length; i++) { 201 TypeBinding parameterType = binding.parameters[i]; 202 TypeBinding argumentType = argumentTypes[i]; 203 arguments[i].computeConversion(scope, parameterType, argumentType); 204 if (argumentType.needsUncheckedConversion(parameterType)) { 205 scope.problemReporter().unsafeTypeConversion(arguments[i], argumentType, parameterType); 206 } 207 } 208 if (argsContainCast) { 209 CastExpression.checkNeedForArgumentCasts(scope, null, allocatedType, binding, this.arguments, argumentTypes, this); 210 } 211 } 212 if (allocatedType.isRawType() && this.binding.hasSubstitutedParameters()) { 213 scope.problemReporter().unsafeRawInvocation(this, this.binding); 214 } 215 return allocatedType; 216 } 217 } 218 | Popular Tags |