/** * Creates variable access from a {@link CtVariableReference}. Think to move this method * in the {@link spoon.reflect.factory.CodeFactory} if you think that is a good idea. */ public <T> CtFieldAccess<T> createFieldAccess(CtVariableReference<T> variableReference, CtExpression<?> target, boolean isReadAccess) { CtFieldAccess<T> fieldAccess; if (isReadAccess) { fieldAccess = jdtTreeBuilder.getFactory().Core().createFieldWrite(); } else { fieldAccess = jdtTreeBuilder.getFactory().Core().createFieldRead(); } fieldAccess.setVariable(variableReference); fieldAccess.setTarget(target); return fieldAccess; }
/** * Creates a variable access. */ public <T> CtVariableAccess<T> createVariableRead(CtVariableReference<T> variable, boolean isStatic) { CtVariableAccess<T> va; if (variable instanceof CtFieldReference) { va = factory.Core().createFieldRead(); // creates a this target for non-static fields to avoid name conflicts... if (!isStatic) { ((CtFieldAccess<T>) va).setTarget(createThisAccess(((CtFieldReference<T>) variable).getDeclaringType())); } } else { va = factory.Core().createVariableRead(); } return va.setVariable(variable); }
/** * Creates a field access from its single name. * * @param singleNameReference * Used to build a variable reference and a target which will be contained in the field access. * @return a field access. */ <T> CtFieldAccess<T> createFieldAccess(SingleNameReference singleNameReference) { CtFieldAccess<T> va; if (isLhsAssignment(jdtTreeBuilder.getContextBuilder(), singleNameReference)) { va = jdtTreeBuilder.getFactory().Core().createFieldWrite(); } else { va = jdtTreeBuilder.getFactory().Core().createFieldRead(); } va.setVariable(jdtTreeBuilder.getReferencesBuilder().<T>getVariableReference(singleNameReference.fieldBinding().original())); if (va.getVariable() != null) { final CtFieldReference<T> ref = va.getVariable(); if (ref.isStatic() && !ref.getDeclaringType().isAnonymous()) { va.setTarget(jdtTreeBuilder.getFactory().Code().createTypeAccess(ref.getDeclaringType())); } else if (!ref.isStatic()) { va.setTarget(jdtTreeBuilder.getFactory().Code().createThisAccess(jdtTreeBuilder.getReferencesBuilder().getTypeReference(singleNameReference.actualReceiverType), true)); } } return va; }
/** * In no classpath mode, when we build a field access, we have a binding typed by ProblemBinding. * This binding doesn't contain all information but we can get some of them. * * @param singleNameReference * Used to get the problem binding of the field access and the name of the declaring type. * @return a field access. */ <T> CtFieldAccess<T> createFieldAccessNoClasspath(SingleNameReference singleNameReference) { CtFieldAccess<T> va; if (isLhsAssignment(jdtTreeBuilder.getContextBuilder(), singleNameReference)) { va = jdtTreeBuilder.getFactory().Core().createFieldWrite(); } else { va = jdtTreeBuilder.getFactory().Core().createFieldRead(); } va.setVariable(jdtTreeBuilder.getReferencesBuilder().<T>getVariableReference((ProblemBinding) singleNameReference.binding)); final CtReference declaring = jdtTreeBuilder.getReferencesBuilder().getDeclaringReferenceFromImports(singleNameReference.token); if (declaring instanceof CtTypeReference && va.getVariable() != null) { final CtTypeReference<Object> declaringRef = (CtTypeReference<Object>) declaring; va.setTarget(jdtTreeBuilder.getFactory().Code().createTypeAccess(declaringRef)); va.getVariable().setDeclaringType(declaringRef); va.getVariable().setStatic(true); } return va; }
/** * In no classpath mode, when we build a field access, we have a binding typed by ProblemBinding. * We try to get all information we can get from this binding. * * @param qualifiedNameReference * Used to get the problem binding of the field access and the name of the declaring type. * @return a field access. */ <T> CtFieldAccess<T> createFieldAccessNoClasspath(QualifiedNameReference qualifiedNameReference) { boolean fromAssignment = isLhsAssignment(jdtTreeBuilder.getContextBuilder(), qualifiedNameReference); CtFieldAccess<T> fieldAccess = createFieldAccess(jdtTreeBuilder.getReferencesBuilder().<T>getVariableReference((ProblemBinding) qualifiedNameReference.binding), null, fromAssignment); // In no classpath mode and with qualified name, the type given by JDT is wrong... final char[][] declaringClass = CharOperation.subarray(qualifiedNameReference.tokens, 0, qualifiedNameReference.tokens.length - 1); final MissingTypeBinding declaringType = jdtTreeBuilder.getContextBuilder().compilationunitdeclaration.scope.environment.createMissingType(null, declaringClass); final CtTypeReference<T> declaringRef = jdtTreeBuilder.getReferencesBuilder().getTypeReference(declaringType); fieldAccess.getVariable().setDeclaringType(declaringRef); fieldAccess.getVariable().setStatic(true); fieldAccess.setTarget(jdtTreeBuilder.getFactory().Code().createTypeAccess(declaringRef)); // In no classpath mode and with qualified name, the binding doesn't have a good name. fieldAccess.getVariable() .setSimpleName(createQualifiedTypeName(CharOperation.subarray(qualifiedNameReference.tokens, qualifiedNameReference.tokens.length - 1, qualifiedNameReference.tokens.length))); return fieldAccess; }
CtExpression<?> access(CompilationNode target, AccessType accessType) { List<CtField<?>> accessPath = accessPath(target); CompilationNode thisNodeToAccess = this; while (!target.rootAccessPath.subList(0, min(thisNodeToAccess.rootAccessPath.size(), target.rootAccessPath.size())) .equals(thisNodeToAccess.rootAccessPath)) { thisNodeToAccess = thisNodeToAccess.parent; } CtFieldAccess<?> access = FieldAccessChains.chainToAccess(accessPath, accessType); CtClass<?> classToMerge = thisNodeToAccess.classesToMerge.get(0); CtThisAccess<?> thisAccess = f.Code().createThisAccess(classToMerge.getReference()); // thisAccess.setImplicit(false); if (access != null) { CtFieldAccess<?> innerMostAccess = access; while (innerMostAccess.getTarget() != null) { innerMostAccess = (CtFieldAccess<?>) innerMostAccess.getTarget(); } innerMostAccess.setTarget(thisAccess); return access; } else { return thisAccess; } }
@SuppressWarnings("unchecked") public static CtFieldAccess<?> chainToAccess(List<CtField<?>> chain, AccessType accessType) { CtFieldAccess<?> access = null; for (int i = chain.size() - 1; i >= 0; i--) { CtField<?> field = chain.get(i); CoreFactory coreFactory = field.getFactory().Core(); CtFieldAccess acc = accessType == AccessType.Read ? coreFactory.createFieldRead() : coreFactory.createFieldWrite(); acc.setVariable(field.getReference()); acc.setType(field.getType()); acc.setTarget(access); access = acc; } return access; }
/** * Creates a variable access. */ public <T> CtVariableAccess<T> createVariableRead(CtVariableReference<T> variable, boolean isStatic) { CtVariableAccess<T> va; if (variable instanceof CtFieldReference) { va = factory.Core().createFieldRead(); // creates a this target for non-static fields to avoid name conflicts... if (!isStatic) { ((CtFieldAccess<T>) va).setTarget(createThisAccess(((CtFieldReference<T>) variable).getDeclaringType())); } } else { va = factory.Core().createVariableRead(); } return va.setVariable(variable).setType(variable.getType()); }