]> source.dussan.org Git - aspectj.git/blob
9b6d7ddcc85d141d6ed96f6cd6cf7db2121431ab
[aspectj.git] /
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 v1.0
6  * which accompanies this distribution and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     PARC     initial implementation
11  * ******************************************************************/
12
13 package org.aspectj.ajdt.internal.compiler.ast;
14
15 import java.lang.reflect.Modifier;
16
17 import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
18 import org.aspectj.ajdt.internal.compiler.lookup.EclipseTypeMunger;
19 import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedFieldBinding;
20 import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedHandler;
21 import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
22 import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
23 import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
24 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
25 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
26 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
27 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
28 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
29 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
30 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Statement;
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.codegen.Opcodes;
34 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
35 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
36 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
37 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
38 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
39 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
40 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
41 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
42 import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
43 import org.aspectj.weaver.AjAttribute;
44 import org.aspectj.weaver.AjcMemberMaker;
45 import org.aspectj.weaver.Member;
46 import org.aspectj.weaver.NameMangler;
47 import org.aspectj.weaver.NewFieldTypeMunger;
48 import org.aspectj.weaver.ResolvedMember;
49 import org.aspectj.weaver.ResolvedMemberImpl;
50 import org.aspectj.weaver.ResolvedType;
51 import org.aspectj.weaver.Shadow;
52 import org.aspectj.weaver.UnresolvedType;
53
54 /**
55  * An inter-type field declaration.
56  *
57  * returnType encodes the type of the field selector encodes the name statements is null until resolution when it is filled in from
58  * the initializer
59  *
60  * @author Jim Hugunin
61  */
62 public class InterTypeFieldDeclaration extends InterTypeDeclaration {
63         public Expression initialization;
64         private TypeBinding realFieldType;
65
66         // public InterTypeFieldBinding interBinding;
67
68         public InterTypeFieldDeclaration(CompilationResult result, TypeReference onType) {
69                 super(result, onType);
70         }
71
72         public TypeBinding getRealFieldType() {
73                 return realFieldType;
74         }
75
76         public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
77                 // we don't have a body to parse
78         }
79
80         protected char[] getPrefix() {
81                 return (NameMangler.ITD_PREFIX + "interField$").toCharArray();
82         }
83
84         public void resolveOnType(ClassScope classScope) {
85                 super.resolveOnType(classScope);
86                 if (ignoreFurtherInvestigation) {
87                         return;
88                 }
89                 if (Modifier.isStatic(declaredModifiers) && onTypeBinding.isInterface()) {
90                         scope.problemReporter().signalError(sourceStart, sourceEnd, "static inter-type field on interface not supported");
91                         ignoreFurtherInvestigation = true;
92                 }
93                 if (Modifier.isStatic(declaredModifiers) && typeVariableAliases != null && typeVariableAliases.size() > 0
94                                 && onTypeBinding.isGenericType()) {
95                         scope.problemReporter().signalError(sourceStart, sourceEnd,
96                                         "static intertype field declarations cannot refer to type variables from the target generic type");
97                 }
98
99         }
100
101         public void resolve(ClassScope upperScope) {
102                 if (munger == null) {
103                         ignoreFurtherInvestigation = true;
104                 }
105                 if (ignoreFurtherInvestigation) {
106                         return;
107                 }
108
109                 EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(upperScope);
110                 ResolvedMember sig = munger.getSignature();
111                 UnresolvedType aspectType = world.fromBinding(upperScope.referenceContext.binding);
112
113                 if (sig.getReturnType().equals(UnresolvedType.VOID)
114                                 || (sig.getReturnType().isArray() && (sig.getReturnType().getComponentType().equals(UnresolvedType.VOID)))) {
115                         upperScope.problemReporter().signalError(sourceStart, sourceEnd, "field type can not be void");
116                 }
117
118                 //
119                 // System.err.println("sig: " + sig);
120                 // System.err.println("field: " + world.makeFieldBinding(
121                 // AjcMemberMaker.interFieldClassField(sig, aspectType)));
122
123                 if (initialization != null && initialization instanceof ArrayInitializer) {
124                         // System.err.println("got initializer: " + initialization);
125                         ArrayAllocationExpression aae = new ArrayAllocationExpression();
126                         aae.initializer = (ArrayInitializer) initialization;
127                         ArrayBinding arrayType = (ArrayBinding) world.makeTypeBinding(sig.getReturnType());
128                         aae.type = AstUtil.makeTypeReference(arrayType.leafComponentType());
129                         aae.sourceStart = initialization.sourceStart;
130                         aae.sourceEnd = initialization.sourceEnd;
131                         aae.dimensions = new Expression[arrayType.dimensions];
132                         initialization = aae;
133                 } /*
134                  * else if (initialization!=null) { MethodScope initializationScope = this.scope; TypeBinding fieldType = realFieldType;
135                  * TypeBinding initializationType; this.initialization.setExpectedType(fieldType); // needed in case of generic method
136                  * invocation if (this.initialization instanceof ArrayInitializer) {
137                  *
138                  * if ((initializationType = this.initialization.resolveTypeExpecting(initializationScope, fieldType)) != null) {
139                  * ((ArrayInitializer) this.initialization).binding = (ArrayBinding) initializationType;
140                  * this.initialization.computeConversion(initializationScope, fieldType, initializationType); } } //
141                  * System.err.println("i=>"+initialization); // System.err.println("sasuages=>"+initialization.resolvedType); //
142                  * //initializationType = initialization.resolveType(initializationScope); //
143                  * System.err.println("scope=>"+initializationScope);
144                  *
145                  * else if ((initializationType = this.initialization.resolveType(initializationScope)) != null) {
146                  *
147                  * if (fieldType != initializationType) // must call before computeConversion() and typeMismatchError()
148                  * initializationScope.compilationUnitScope().recordTypeConversion(fieldType, initializationType); if
149                  * (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, fieldType) || (fieldType.isBaseType() &&
150                  * BaseTypeBinding.isWidening(fieldType.id, initializationType.id)) || initializationType.isCompatibleWith(fieldType)) {
151                  * initialization.computeConversion(initializationScope, fieldType, initializationType); if
152                  * (initializationType.needsUncheckedConversion(fieldType)) {
153                  * initializationScope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, fieldType); } } else
154                  * if (initializationScope.isBoxingCompatibleWith(initializationType, fieldType) || (initializationType.isBaseType() //
155                  * narrowing then boxing ? && initializationScope.compilerOptions().sourceLevel >= JDK1_5 // autoboxing &&
156                  * !fieldType.isBaseType() && initialization.isConstantValueOfTypeAssignableToType(initializationType,
157                  * initializationScope.environment().computeBoxingType(fieldType)))) {
158                  * this.initialization.computeConversion(initializationScope, fieldType, initializationType); } else {
159                  * initializationScope.problemReporter().typeMismatchError(initializationType, fieldType, this); } // if
160                  * (this.binding.isFinal()){ // cast from constant actual type to variable type //
161                  * this.binding.setConstant(this.initialization.constant.castTo((this.binding.returnType.id << 4) +
162                  * this.initialization.constant.typeID())); // } // } else { // this.binding.setConstant(NotAConstant); } // }
163                  */
164
165                 // ////////////////////
166
167                 if (initialization == null) {
168                         this.statements = new Statement[] { new ReturnStatement(null, 0, 0), };
169                 } else if (!onTypeBinding.isInterface()) {
170                         MethodBinding writeMethod = world.makeMethodBinding(AjcMemberMaker.interFieldSetDispatcher(sig, aspectType),
171                                         munger.getTypeVariableAliases());
172                         // For the body of an intertype field initalizer, generate a call to the inter field set dispatcher
173                         // method as that casts the shadow of a field set join point.
174                         if (Modifier.isStatic(declaredModifiers)) {
175                                 this.statements = new Statement[] { new KnownMessageSend(writeMethod,
176                                                 AstUtil.makeNameReference(writeMethod.declaringClass), new Expression[] { initialization }), };
177                         } else {
178                                 this.statements = new Statement[] { new KnownMessageSend(writeMethod,
179                                                 AstUtil.makeNameReference(writeMethod.declaringClass), new Expression[] {
180                                                                 AstUtil.makeLocalVariableReference(arguments[0].binding), initialization }), };
181                         }
182                 } else {
183                         // XXX something is broken about this logic. Can we write to static interface fields?
184                         MethodBinding writeMethod = world.makeMethodBinding(
185                                         AjcMemberMaker.interFieldInterfaceSetter(sig, sig.getDeclaringType().resolve(world.getWorld()), aspectType),
186                                         munger.getTypeVariableAliases());
187                         if (Modifier.isStatic(declaredModifiers)) {
188                                 this.statements = new Statement[] { new KnownMessageSend(writeMethod,
189                                                 AstUtil.makeNameReference(writeMethod.declaringClass), new Expression[] { initialization }), };
190                         } else {
191                                 this.statements = new Statement[] { new KnownMessageSend(writeMethod,
192                                                 AstUtil.makeLocalVariableReference(arguments[0].binding), new Expression[] { initialization }), };
193                         }
194                 }
195
196                 super.resolve(upperScope);
197         }
198
199         public void setInitialization(Expression initialization) {
200                 this.initialization = initialization;
201
202         }
203
204         /*
205          * public void resolveStatements() { super.resolveStatements();
206          *
207          * // if (initialization!=null) { // MethodScope initializationScope = this.scope; // TypeBinding fieldType = realFieldType; //
208          * TypeBinding initializationType; // this.initialization.setExpectedType(fieldType); // needed in case of generic method
209          * invocation // if (this.initialization instanceof ArrayInitializer) { // // if ((initializationType =
210          * this.initialization.resolveTypeExpecting(initializationScope, fieldType)) != null) { // ((ArrayInitializer)
211          * this.initialization).binding = (ArrayBinding) initializationType; //
212          * this.initialization.computeConversion(initializationScope, fieldType, initializationType); // } // } ////
213          * System.err.println("i=>"+initialization); //// System.err.println("sasuages=>"+initialization.resolvedType); ////
214          * //initializationType = initialization.resolveType(initializationScope); ////
215          * System.err.println("scope=>"+initializationScope); // // else if ((initializationType =
216          * this.initialization.resolveType(initializationScope)) != null) { // // if (fieldType != initializationType) // must call
217          * before computeConversion() and typeMismatchError() //
218          * initializationScope.compilationUnitScope().recordTypeConversion(fieldType, initializationType); // if
219          * (this.initialization.isConstantValueOfTypeAssignableToType(initializationType, fieldType) // || (fieldType.isBaseType() &&
220          * BaseTypeBinding.isWidening(fieldType.id, initializationType.id)) // || initializationType.isCompatibleWith(fieldType)) { //
221          * initialization.computeConversion(initializationScope, fieldType, initializationType); // if
222          * (initializationType.needsUncheckedConversion(fieldType)) { //
223          * initializationScope.problemReporter().unsafeTypeConversion(this.initialization, initializationType, fieldType); // } // }
224          * else if (initializationScope.isBoxingCompatibleWith(initializationType, fieldType) // || (initializationType.isBaseType() //
225          * narrowing then boxing ? // && initializationScope.compilerOptions().sourceLevel >= JDK1_5 // autoboxing // &&
226          * !fieldType.isBaseType() // && initialization.isConstantValueOfTypeAssignableToType(initializationType,
227          * initializationScope.environment().computeBoxingType(fieldType)))) { //
228          * this.initialization.computeConversion(initializationScope, fieldType, initializationType); // } else { //
229          * initializationScope.problemReporter().typeMismatchError(initializationType, fieldType, this); // } // // if
230          * (this.binding.isFinal()){ // cast from constant actual type to variable type // //
231          * this.binding.setConstant(this.initialization.constant.castTo((this.binding.returnType.id << 4) +
232          * this.initialization.constant.typeID())); // // } // // } else { // // this.binding.setConstant(NotAConstant); // }}
233          *
234          * }
235          */
236         public EclipseTypeMunger build(ClassScope classScope) {
237                 EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(classScope);
238                 resolveOnType(classScope);
239
240                 if (ignoreFurtherInvestigation) {
241                         return null;
242                 }
243
244                 binding = classScope.referenceContext.binding.resolveTypesFor(binding);
245                 if (ignoreFurtherInvestigation) {
246                         return null;
247                 }
248
249                 if (isTargetAnnotation(classScope, "field")) {
250                         return null; // Error message output in isTargetAnnotation
251                 }
252                 if (isTargetEnum(classScope, "field")) {
253                         return null; // Error message output in isTargetEnum
254                 }
255
256                 if (!Modifier.isStatic(declaredModifiers)) {
257                         super.binding.parameters = new TypeBinding[] { onTypeBinding, };
258                         this.arguments = new Argument[] { AstUtil.makeFinalArgument("ajc$this_".toCharArray(), onTypeBinding), };
259                 }
260
261                 // System.err.println("type: " + binding.returnType + ", " + returnType);
262                 ResolvedType declaringType = world.fromBinding(onTypeBinding).resolve(world.getWorld());
263                 if (declaringType.isRawType() || declaringType.isParameterizedType()) {
264                         declaringType = declaringType.getGenericType();
265                 }
266
267                 if (interTypeScope == null) {
268                         return null; // We encountered a problem building the scope, don't continue - error already reported
269                 }
270
271                 // Build a half correct resolvedmember (makeResolvedMember understands tvars) then build a fully correct sig from it
272                 ResolvedMember sigtemp = world.makeResolvedMemberForITD(binding, onTypeBinding, interTypeScope.getRecoveryAliases());
273                 UnresolvedType returnType = sigtemp.getReturnType();
274                 // if (returnType.isParameterizedType() || returnType.isGenericType()) returnType = returnType.getRawType();
275                 ResolvedMember sig = new ResolvedMemberImpl(Member.FIELD, declaringType, declaredModifiers, returnType, new String(
276                                 declaredSelector), UnresolvedType.NONE);
277                 sig.setTypeVariables(sigtemp.getTypeVariables());
278
279                 NewFieldTypeMunger myMunger = new NewFieldTypeMunger(sig, null, typeVariableAliases);
280                 if (world.getItdVersion() == 1) {
281                         myMunger.version = NewFieldTypeMunger.VersionOne;
282                 }
283                 setMunger(myMunger);
284                 ResolvedType aspectType = world.fromEclipse(classScope.referenceContext.binding);
285                 ResolvedMember me = myMunger.getInitMethod(aspectType);
286                 this.selector = binding.selector = me.getName().toCharArray();
287                 this.realFieldType = this.binding.returnType;
288                 this.binding.returnType = TypeBinding.VOID;
289                 // ??? all other pieces should already match
290
291                 return new EclipseTypeMunger(world, myMunger, aspectType, this);
292         }
293
294         private AjAttribute makeAttribute() {
295                 return new AjAttribute.TypeMunger(munger);
296         }
297
298         public void generateCode(ClassScope classScope, ClassFile classFile) {
299                 if (ignoreFurtherInvestigation) {
300                         return;
301                 }
302
303                 classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute()));
304                 super.generateCode(classScope, classFile);
305                 generateDispatchMethods(classScope, classFile);
306                 // interBinding.reader.generateMethod(this, classScope, classFile);
307                 // interBinding.writer.generateMethod(this, classScope, classFile);
308         }
309
310         private void generateDispatchMethods(ClassScope classScope, ClassFile classFile) {
311                 EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(classScope);
312                 ResolvedMember sig = munger.getSignature();
313                 UnresolvedType aspectType = world.fromBinding(classScope.referenceContext.binding);
314                 generateDispatchMethod(world, sig, aspectType, classScope, classFile, true);
315                 generateDispatchMethod(world, sig, aspectType, classScope, classFile, false);
316         }
317
318         private void generateDispatchMethod(EclipseFactory world, ResolvedMember sig, UnresolvedType aspectType, ClassScope classScope,
319                         ClassFile classFile, boolean isGetter) {
320                 MethodBinding binding;
321                 if (isGetter) {
322                         binding = world.makeMethodBinding(AjcMemberMaker.interFieldGetDispatcher(sig, aspectType),
323                                         munger.getTypeVariableAliases(), munger.getSignature().getDeclaringType());
324                 } else {
325                         binding = world.makeMethodBinding(AjcMemberMaker.interFieldSetDispatcher(sig, aspectType),
326                                         munger.getTypeVariableAliases(), munger.getSignature().getDeclaringType());
327                 }
328                 classFile.generateMethodInfoHeader(binding);
329                 int methodAttributeOffset = classFile.contentsOffset;
330                 int attributeNumber = classFile.generateMethodInfoAttributes(binding, makeEffectiveSignatureAttribute(sig, isGetter ? Shadow.FieldGet : Shadow.FieldSet, false));
331                 int codeAttributeOffset = classFile.contentsOffset;
332                 classFile.generateCodeAttributeHeader();
333                 CodeStream codeStream = classFile.codeStream;
334                 codeStream.reset(this, classFile);
335
336                 NewFieldTypeMunger fieldMunger = (NewFieldTypeMunger) munger;
337
338                 // Force use of version 1 if there is a field with that name on the type already
339                 if (world.getItdVersion() == 1) {
340                         fieldMunger.version = NewFieldTypeMunger.VersionOne;
341                 } else {
342                         if (!onTypeBinding.isInterface()) {
343                                 FieldBinding[] existingFields = onTypeBinding.fields();
344                                 for (int f = 0; f < existingFields.length; f++) {
345                                         FieldBinding fieldBinding = existingFields[f];
346                                         if (CharOperation.equals(fieldBinding.name, sig.getName().toCharArray())) {
347                                                 fieldMunger.version = NewFieldTypeMunger.VersionOne;
348                                         }
349                                 }
350                         }
351                 }
352
353                 FieldBinding classField = world.makeFieldBinding(
354                                 AjcMemberMaker.interFieldClassField(sig, aspectType, fieldMunger.version == NewFieldTypeMunger.VersionTwo),
355                                 munger.getTypeVariableAliases());
356
357                 codeStream.initializeMaxLocals(binding);
358                 if (isGetter) {
359                         if (onTypeBinding.isInterface()) {
360                                 UnresolvedType declaringTX = sig.getDeclaringType();
361                                 ResolvedType declaringRTX = world.getWorld().resolve(declaringTX, munger.getSourceLocation());
362                                 MethodBinding readMethod = world.makeMethodBinding(
363                                                 AjcMemberMaker.interFieldInterfaceGetter(sig, declaringRTX, aspectType), munger.getTypeVariableAliases());
364                                 generateInterfaceReadBody(binding, readMethod, codeStream);
365                         } else {
366                                 generateClassReadBody(binding, classField, codeStream);
367                         }
368                 } else {
369                         if (onTypeBinding.isInterface()) {
370                                 MethodBinding writeMethod = world.makeMethodBinding(
371                                                 AjcMemberMaker.interFieldInterfaceSetter(sig,
372                                                                 world.getWorld().resolve(sig.getDeclaringType(), munger.getSourceLocation()), aspectType),
373                                                 munger.getTypeVariableAliases());
374                                 generateInterfaceWriteBody(binding, writeMethod, codeStream);
375                         } else {
376                                 generateClassWriteBody(binding, classField, codeStream);
377                         }
378                 }
379                 AstUtil.generateReturn(binding.returnType, codeStream);
380
381                 classFile.completeCodeAttribute(codeAttributeOffset,scope);
382                 attributeNumber++;
383                 classFile.completeMethodInfo(binding,methodAttributeOffset, attributeNumber);
384         }
385
386         private void generateInterfaceReadBody(MethodBinding binding, MethodBinding readMethod, CodeStream codeStream) {
387                 codeStream.aload_0();
388                 codeStream.invoke(Opcodes.OPC_invokeinterface,readMethod,null);
389         }
390
391         private void generateInterfaceWriteBody(MethodBinding binding, MethodBinding writeMethod, CodeStream codeStream) {
392                 codeStream.aload_0();
393                 codeStream.load(writeMethod.parameters[0], 1);
394                 codeStream.invoke(Opcodes.OPC_invokeinterface, writeMethod, null);
395         }
396
397         private void generateClassReadBody(MethodBinding binding, FieldBinding field, CodeStream codeStream) {
398                 if (field.isPrivate() || !field.canBeSeenBy(binding.declaringClass.fPackage)) {
399
400                         PrivilegedHandler handler = (PrivilegedHandler) Scope.findPrivilegedHandler(binding.declaringClass);
401                         if (handler == null) {
402                                 // one is now required!
403                                 ReferenceBinding typebinding = binding.declaringClass;
404                                 if (typebinding instanceof ReferenceBinding) {
405                                         SourceTypeBinding sourceBinding = (SourceTypeBinding) typebinding;
406                                         handler = new PrivilegedHandler((AspectDeclaration) sourceBinding.scope.referenceContext);
407                                         sourceBinding.privilegedHandler = handler;
408                                 }
409                         }
410                         PrivilegedFieldBinding fBinding = (PrivilegedFieldBinding) handler.getPrivilegedAccessField(field, null);
411
412                         if (field.isStatic()) {
413                                 codeStream.invoke(Opcodes.OPC_invokestatic,fBinding.reader,null);
414                         } else {
415                                 codeStream.aload_0();
416                                 codeStream.invoke(Opcodes.OPC_invokestatic,fBinding.reader,null);
417                         }
418                         return;
419                 }
420                 if (field.isStatic()) {
421                         codeStream.fieldAccess(Opcodes.OPC_getstatic,field,null);
422                 } else {
423                         codeStream.aload_0();
424                         codeStream.fieldAccess(Opcodes.OPC_getfield,field,null);
425                 }
426         }
427
428         private void generateClassWriteBody(MethodBinding binding, FieldBinding field, CodeStream codeStream) {
429                 if (field.isPrivate() || !field.canBeSeenBy(binding.declaringClass.fPackage)) {
430                         PrivilegedFieldBinding fBinding = (PrivilegedFieldBinding) Scope.findPrivilegedHandler(binding.declaringClass)
431                                         .getPrivilegedAccessField(field, null);
432                         if (field.isStatic()) {
433                                 codeStream.load(field.type, 0);
434                                 codeStream.invoke(Opcodes.OPC_invokestatic,fBinding.writer,null);
435                         } else {
436                                 codeStream.aload_0();
437                                 codeStream.load(field.type, 1);
438                                 codeStream.invoke(Opcodes.OPC_invokestatic,fBinding.writer,null);
439                         }
440                         return;
441                 }
442                 if (field.isStatic()) {
443                         codeStream.load(field.type, 0);
444                         codeStream.fieldAccess(Opcodes.OPC_putstatic,field,null);
445                 } else {
446                         codeStream.aload_0();
447                         codeStream.load(field.type, 1);
448                         codeStream.fieldAccess(Opcodes.OPC_putfield,field,null);
449                 }
450         }
451
452         protected Shadow.Kind getShadowKindForBody() {
453                 return null;
454         }
455
456 }