private void checkFinalFieldAccess(Expression expression) { if (!(expression instanceof VariableExpression) && !(expression instanceof PropertyExpression)) return; Variable v = null; if (expression instanceof VariableExpression) { VariableExpression ve = (VariableExpression) expression; v = ve.getAccessedVariable(); } else { PropertyExpression propExp = ((PropertyExpression) expression); Expression objectExpression = propExp.getObjectExpression(); if (objectExpression instanceof VariableExpression) { VariableExpression varExp = (VariableExpression) objectExpression; if (varExp.isThisExpression()) { v = currentClass.getDeclaredField(propExp.getPropertyAsString()); } } } if (v instanceof FieldNode) { FieldNode fn = (FieldNode) v; /* * if it is static final but not accessed inside a static constructor, or, * if it is an instance final but not accessed inside a instance constructor, it is an error */ boolean isFinal = fn.isFinal(); boolean isStatic = fn.isStatic(); boolean error = isFinal && ((isStatic && !inStaticConstructor) || (!isStatic && !inConstructor)); if (error) addError( "cannot modify" + (isStatic ? " static" : "") + " final field '" + fn.getName() + "' outside of " + (isStatic ? "static initialization block." : "constructor."), expression); } }
protected Expression transformMethodCallExpression(MethodCallExpression mce) { Expression args = transform(mce.getArguments()); Expression method = transform(mce.getMethod()); Expression object = transform(mce.getObjectExpression()); boolean isExplicitThisOrSuper = false; boolean isExplicitSuper = false; if (object instanceof VariableExpression) { VariableExpression ve = (VariableExpression) object; isExplicitThisOrSuper = !mce.isImplicitThis() && (ve.isThisExpression() || ve.isSuperExpression()); isExplicitSuper = ve.isSuperExpression(); } if (mce.isImplicitThis() || isExplicitThisOrSuper) { if (mce.isImplicitThis()) { Expression ret = findStaticMethodImportFromModule(method, args); if (ret != null) { setSourcePosition(ret, mce); return ret; } if (method instanceof ConstantExpression && !inLeftExpression) { // could be a closure field String methodName = (String) ((ConstantExpression) method).getValue(); ret = findStaticFieldOrPropAccessorImportFromModule(methodName); if (ret != null) { ret = new MethodCallExpression(ret, "call", args); setSourcePosition(ret, mce); return ret; } } } else if (currentMethod != null && currentMethod.isStatic() && isExplicitSuper) { MethodCallExpression ret = new MethodCallExpression( new ClassExpression(currentClass.getSuperClass()), method, args); setSourcePosition(ret, mce); return ret; } if (method instanceof ConstantExpression) { ConstantExpression ce = (ConstantExpression) method; Object value = ce.getValue(); if (value instanceof String) { String methodName = (String) value; boolean lookForPossibleStaticMethod = !methodName.equals("call"); if (currentMethod != null && !currentMethod.isStatic()) { if (currentClass.hasPossibleMethod(methodName, args)) { lookForPossibleStaticMethod = false; } } if (!inClosure && (inSpecialConstructorCall || (lookForPossibleStaticMethod && currentClass.hasPossibleStaticMethod(methodName, args)))) { StaticMethodCallExpression smce = new StaticMethodCallExpression(currentClass, methodName, args); setSourcePosition(smce, mce); return smce; } } } } MethodCallExpression result = new MethodCallExpression(object, method, args); result.setSafe(mce.isSafe()); result.setImplicitThis(mce.isImplicitThis()); result.setSpreadSafe(mce.isSpreadSafe()); result.setMethodTarget(mce.getMethodTarget()); // GROOVY-6757 result.setGenericsTypes(mce.getGenericsTypes()); setSourcePosition(result, mce); return result; }