private static void markDynamicCall(final MethodCallExpression mce, final FieldNode fn, final boolean isStatic) { if (isStatic) { mce.putNodeMetaData(TraitASTTransformation.DO_DYNAMIC, fn.getOriginType()); } }
private boolean storeField(FieldNode field, boolean returnTrueIfFieldExists, PropertyExpression expressionToStoreOn, ClassNode receiver, ClassCodeVisitorSupport visitor, String delegationData, boolean lhsOfAssignment) { if (field == null || !returnTrueIfFieldExists) return false; if (visitor != null) visitor.visitField(field); storeWithResolve(field.getOriginType(), receiver, field.getDeclaringClass(), field.isStatic(), expressionToStoreOn); checkOrMarkPrivateAccess(expressionToStoreOn, field, lhsOfAssignment); if (delegationData != null) { expressionToStoreOn.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, delegationData); } return true; }
public void visitField(FieldNode node) { // Do not visit fields which are manually added due to optimization if (!node.getName().startsWith("$")) { visitType(node.getOriginType()); visitNode(node); super.visitField(node); } }
protected ClassNode getOriginalDeclarationType(Expression lhs) { if (lhs instanceof VariableExpression) { Variable var = findTargetVariable((VariableExpression) lhs); if (var instanceof PropertyNode) { // Do NOT trust the type of the property node! return getType(lhs); } if (var instanceof DynamicVariable) return getType(lhs); return var.getOriginType(); } if (lhs instanceof FieldExpression) { return ((FieldExpression) lhs).getField().getOriginType(); } return getType(lhs); }
@Override public void visitField(final FieldNode node) { final boolean osc = typeCheckingContext.isInStaticContext; try { typeCheckingContext.isInStaticContext = node.isInStaticContext(); currentField = node; super.visitField(node); Expression init = node.getInitialExpression(); if (init != null) { FieldExpression left = new FieldExpression(node); BinaryExpression bexp = binX( left, Token.newSymbol("=", node.getLineNumber(), node.getColumnNumber()), init ); bexp.setSourcePosition(init); typeCheckAssignment(bexp, left, node.getOriginType(), init, getType(init)); if (init instanceof ConstructorCallExpression) { inferDiamondType((ConstructorCallExpression) init, node.getOriginType()); } } } finally { currentField = null; typeCheckingContext.isInStaticContext = osc; } }
fieldNode.getName() )); MethodNode accessor = node.addMethod("pfaccess$" + acc, access, fieldNode.getOriginType(), new Parameter[]{param}, ClassNode.EMPTY_ARRAY, stmt); privateFieldAccessors.put(fieldNode.getName(), accessor); Parameter param = new Parameter(node.getPlainNodeReference(), "$that"); Expression receiver = fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param); Parameter value = new Parameter(fieldNode.getOriginType(), "$value"); Statement stmt = GeneralUtils.assignS( new PropertyExpression(receiver, fieldNode.getName()), new VariableExpression(value) ); MethodNode mutator = node.addMethod("pfaccess$0" + acc, access, fieldNode.getOriginType(), new Parameter[]{param, value}, ClassNode.EMPTY_ARRAY, stmt); privateFieldMutators.put(fieldNode.getName(), mutator);
/** * Given a field node, checks if we are accessing or setting a private field from an inner class. */ private void checkOrMarkPrivateAccess(Expression source, FieldNode fn, boolean lhsOfAssignment) { ClassNode enclosingClassNode = typeCheckingContext.getEnclosingClassNode(); ClassNode declaringClass = fn.getDeclaringClass(); if (fn != null && Modifier.isPrivate(fn.getModifiers()) && (declaringClass != enclosingClassNode || typeCheckingContext.getEnclosingClosure() != null) && declaringClass.getModule() == enclosingClassNode.getModule()) { if (!lhsOfAssignment && enclosingClassNode.isDerivedFrom(declaringClass)) { // check for a public/protected getter since JavaBean getters haven't been recognised as properties // at this point and we don't want private field access for that case which will be handled later boolean isPrimBool = fn.getOriginType().equals(ClassHelper.boolean_TYPE); String suffix = Verifier.capitalize(fn.getName()); MethodNode getterNode = findValidGetter(enclosingClassNode, "get" + suffix); if (getterNode == null && isPrimBool) { getterNode = findValidGetter(enclosingClassNode, "is" + suffix); } if (getterNode != null) { source.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, getterNode.getReturnType()); return; } } StaticTypesMarker marker = lhsOfAssignment ? StaticTypesMarker.PV_FIELDS_MUTATION : StaticTypesMarker.PV_FIELDS_ACCESS; addPrivateFieldOrMethodAccess(source, declaringClass, marker, fn); } }
public ClassNode resolveType(final Expression exp, final ClassNode current) { if (exp instanceof ClassExpression) return ClassHelper.CLASS_Type; OptimizingStatementWriter.StatementMeta meta = exp.getNodeMetaData(OptimizingStatementWriter.StatementMeta.class); ClassNode type = null; if (meta != null) type = meta.type; if (type != null) return type; if (exp instanceof VariableExpression) { VariableExpression ve = (VariableExpression) exp; if (ve.isClosureSharedVariable()) return ve.getType(); type = ve.getOriginType(); if (ve.getAccessedVariable() instanceof FieldNode) { FieldNode fn = (FieldNode) ve.getAccessedVariable(); if (!fn.getDeclaringClass().equals(current)) return fn.getOriginType(); } } else if (exp instanceof Variable) { Variable v = (Variable) exp; type = v.getOriginType(); } else { type = exp.getType(); } return type.redirect(); } }
private static Expression tryTransformPrivateFieldAccess(VariableExpression expr) { FieldNode field = expr.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS); if (field == null) { field = expr.getNodeMetaData(StaticTypesMarker.PV_FIELDS_MUTATION); } if (field != null) { // access to a private field from a section of code that normally doesn't have access to it, like a // closure or an inner class VariableExpression receiver = new VariableExpression("this"); PropertyExpression pexp = new PropertyExpression( receiver, expr.getName() ); pexp.setImplicitThis(true); pexp.getProperty().setSourcePosition(expr); // put the receiver inferred type so that the class writer knows that it will have to call a bridge method receiver.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, field.getDeclaringClass()); // add inferred type information pexp.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, field.getOriginType()); return pexp; } return null; } }
baseName + Traits.remappedFieldName(trait, field.getName()), ACC_STATIC | ACC_PUBLIC | ACC_SYNTHETIC, field.getOriginType(), new Parameter[]{createSelfParameter(trait, field.isStatic())}, ClassNode.EMPTY_ARRAY, new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject), Traits.helperSetterName(field), new CastExpression(field.getOriginType(),initCode.getExpression()) ); Traits.helperSetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), new Parameter[]{new Parameter(field.getOriginType(), "val")}, ClassNode.EMPTY_ARRAY, null Traits.helperGetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, dummyFieldName, ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, field.getOriginType(), fieldHelper, null
private void storeThisInstanceField(FieldExpression expression) { MethodVisitor mv = controller.getMethodVisitor(); FieldNode field = expression.getField(); boolean setReferenceFromReference = field.isHolder() && expression.isUseReferenceDirectly(); String ownerName = (field.getOwner().equals(controller.getClassNode())) ? controller.getInternalClassName() : BytecodeHelper.getClassInternalName(field.getOwner()); OperandStack operandStack = controller.getOperandStack(); if (setReferenceFromReference) { // rhs is ready to use reference, just put it in the field mv.visitVarInsn(ALOAD, 0); operandStack.push(controller.getClassNode()); operandStack.swap(); mv.visitFieldInsn(PUTFIELD, ownerName, field.getName(), BytecodeHelper.getTypeDescription(field.getType())); } else if (field.isHolder()){ // rhs is normal value, set the value in the Reference operandStack.doGroovyCast(field.getOriginType()); operandStack.box(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, ownerName, expression.getFieldName(), BytecodeHelper.getTypeDescription(field.getType())); mv.visitInsn(SWAP); mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "set", "(Ljava/lang/Object;)V", false); } else { // rhs is normal value, set normal value operandStack.doGroovyCast(field.getOriginType()); mv.visitVarInsn(ALOAD, 0); operandStack.push(controller.getClassNode()); operandStack.swap(); mv.visitFieldInsn(PUTFIELD, ownerName, field.getName(), BytecodeHelper.getTypeDescription(field.getType())); } }
operandStack.doGroovyCast(fn.getOriginType()); mv.visitFieldInsn(fn.isStatic() ? PUTSTATIC : PUTFIELD, BytecodeHelper.getClassInternalName(fn.getOwner()), property, BytecodeHelper.getTypeDescription(fn.getOriginType())); operandStack.remove(fn.isStatic()?1:2); return true;
fieldNode.getOriginType().getUnresolvedName(), makeDeclaringAndActualGenericsTypeMap(fieldNode.getDeclaringClass(), typeCheckingContext.getEnclosingClassNode()) );
return getGenericsResolvedTypeOfFieldOrProperty(fn, fn.getOriginType());
CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); ClassNode replacementType = field.getOriginType(); OperandStack operandStack = controller.getOperandStack(); if (field.isStatic()) {
} else if (field.isHolder()){ operandStack.doGroovyCast(field.getOriginType()); operandStack.box(); mv.visitVarInsn(ALOAD, 0); } else { operandStack.doGroovyCast(field.getOriginType()); mv.visitVarInsn(ALOAD, 0); operandStack.push(controller.getClassNode());