|
142 | 142 |
|
143 | 143 | import static java.util.stream.Collectors.toMap; |
144 | 144 | import static org.apache.groovy.ast.tools.ClassNodeUtils.samePackageName; |
| 145 | +import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression; |
145 | 146 | import static org.codehaus.groovy.ast.ClassHelper.BigDecimal_TYPE; |
146 | 147 | import static org.codehaus.groovy.ast.ClassHelper.BigInteger_TYPE; |
147 | 148 | import static org.codehaus.groovy.ast.ClassHelper.Boolean_TYPE; |
|
207 | 208 | import static org.codehaus.groovy.ast.tools.WideningCategories.lowestUpperBound; |
208 | 209 | import static org.codehaus.groovy.classgen.AsmClassGenerator.MINIMUM_BYTECODE_VERSION; |
209 | 210 | import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean; |
| 211 | +import static org.codehaus.groovy.runtime.DefaultGroovyMethods.first; |
210 | 212 | import static org.codehaus.groovy.syntax.Types.ASSIGN; |
211 | 213 | import static org.codehaus.groovy.syntax.Types.ASSIGNMENT_OPERATOR; |
212 | 214 | import static org.codehaus.groovy.syntax.Types.COMPARE_EQUAL; |
@@ -576,21 +578,17 @@ private void checkOrMarkPrivateAccess(Expression source, MethodNode mn) { |
576 | 578 | } |
577 | 579 |
|
578 | 580 | private void checkSuperCallFromClosure(Expression call, MethodNode directCallTarget) { |
579 | | - if (call instanceof MethodCallExpression && typeCheckingContext.getEnclosingClosure() != null) { |
580 | | - Expression objectExpression = ((MethodCallExpression) call).getObjectExpression(); |
581 | | - if (objectExpression instanceof VariableExpression) { |
582 | | - VariableExpression var = (VariableExpression) objectExpression; |
583 | | - if (var.isSuperExpression()) { |
584 | | - ClassNode current = typeCheckingContext.getEnclosingClassNode(); |
585 | | - LinkedList<MethodNode> list = current.getNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED); |
586 | | - if (list == null) { |
587 | | - list = new LinkedList<MethodNode>(); |
588 | | - current.putNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED, list); |
589 | | - } |
590 | | - list.add(directCallTarget); |
591 | | - call.putNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED, current); |
592 | | - } |
| 581 | + if (call instanceof MethodCallExpression |
| 582 | + && typeCheckingContext.getEnclosingClosure() != null |
| 583 | + && isSuperExpression(((MethodCallExpression) call).getObjectExpression())) { |
| 584 | + ClassNode current = typeCheckingContext.getEnclosingClassNode(); |
| 585 | + LinkedList<MethodNode> list = current.getNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED); |
| 586 | + if (list == null) { |
| 587 | + list = new LinkedList<MethodNode>(); |
| 588 | + current.putNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED, list); |
593 | 589 | } |
| 590 | + list.add(directCallTarget); |
| 591 | + call.putNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED, current); |
594 | 592 | } |
595 | 593 | } |
596 | 594 |
|
@@ -1782,8 +1780,13 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re |
1782 | 1780 | ClassNode rawType = objectExpressionType.getPlainNodeReference(); |
1783 | 1781 | inferDiamondType((ConstructorCallExpression) objectExpression, rawType); |
1784 | 1782 | } |
1785 | | - // GRECLIPSE end |
| 1783 | + /* GRECLIPSE edit -- enclosing excludes classes that skip STC |
1786 | 1784 | List<ClassNode> enclosingTypes = typeCheckingContext.getEnclosingClassNodes(); |
| 1785 | + */ |
| 1786 | + Set<ClassNode> enclosingTypes = new LinkedHashSet<>(); |
| 1787 | + enclosingTypes.add(typeCheckingContext.getEnclosingClassNode()); |
| 1788 | + enclosingTypes.addAll( first(enclosingTypes).getOuterClasses()); |
| 1789 | + // GRECLIPSE end |
1787 | 1790 | boolean staticOnlyAccess = isClassClassNodeWrappingConcreteType(objectExpressionType); |
1788 | 1791 | if ("this".equals(propertyName) && staticOnlyAccess) { |
1789 | 1792 | // Outer.this for any level of nesting |
@@ -1912,7 +1915,8 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re |
1912 | 1915 | boolean checkGetterOrSetter = !isThisExpression || propertyNode == null; |
1913 | 1916 |
|
1914 | 1917 | if (readMode && checkGetterOrSetter) { |
1915 | | - if (getter != null) { |
| 1918 | + if (getter != null // GRECLIPSE add -- GROOVY-6277 |
| 1919 | + && hasAccessToMember(first(enclosingTypes), getter.getDeclaringClass(), getter.getModifiers())) { |
1916 | 1920 | ClassNode cn = inferReturnTypeGenerics(current, getter, ArgumentListExpression.EMPTY_ARGUMENTS); |
1917 | 1921 | storeInferredTypeForPropertyExpression(pexp, cn); |
1918 | 1922 | storeTargetMethod(pexp, getter); |
@@ -2052,14 +2056,14 @@ private static boolean hasAccessToField(FieldNode field, ClassNode objectExpress |
2052 | 2056 | return false; |
2053 | 2057 | } |
2054 | 2058 | */ |
2055 | | - private static boolean hasAccessToField(ClassNode accessor, FieldNode field) { |
2056 | | - if (field.isPublic() || accessor.equals(field.getDeclaringClass())) { |
| 2059 | + private static boolean hasAccessToMember(final ClassNode sender, final ClassNode receiver, final int modifiers) { |
| 2060 | + if (Modifier.isPublic(modifiers) || sender.equals(receiver) || sender.getOuterClasses().contains(receiver)) { |
2057 | 2061 | return true; |
2058 | 2062 | } |
2059 | | - if (field.isProtected()) { |
2060 | | - return accessor.isDerivedFrom(field.getDeclaringClass()); |
| 2063 | + if (Modifier.isProtected(modifiers)) { |
| 2064 | + return sender.isDerivedFrom(receiver); |
2061 | 2065 | } else { |
2062 | | - return !field.isPrivate() && Objects.equals(accessor.getPackageName(), field.getDeclaringClass().getPackageName()); |
| 2066 | + return !Modifier.isPrivate(modifiers) && Objects.equals(sender.getPackageName(), receiver.getPackageName()); |
2063 | 2067 | } |
2064 | 2068 | } |
2065 | 2069 | // GRECLIPSE end |
@@ -2218,8 +2222,7 @@ private boolean storeField(FieldNode field, boolean returnTrueIfFieldExists, Pro |
2218 | 2222 | if (visitor != null) visitor.visitField(field); |
2219 | 2223 | checkOrMarkPrivateAccess(expressionToStoreOn, field, lhsOfAssignment); |
2220 | 2224 | // GRECLIPSE add |
2221 | | - Expression objectExpression = expressionToStoreOn.getObjectExpression(); |
2222 | | - boolean accessible = hasAccessToField(objectExpression instanceof VariableExpression && ((VariableExpression) objectExpression).isSuperExpression() ? typeCheckingContext.getEnclosingClassNode() : receiver, field); |
| 2225 | + boolean accessible = hasAccessToMember(isSuperExpression(expressionToStoreOn.getObjectExpression()) ? typeCheckingContext.getEnclosingClassNode() : receiver, field.getDeclaringClass(), field.getModifiers()); |
2223 | 2226 | if (expressionToStoreOn instanceof AttributeExpression) { |
2224 | 2227 | if (!accessible) { |
2225 | 2228 | addStaticTypeError("The field " + field.getDeclaringClass().getNameWithoutPackage() + "." + field.getName() + " is not accessible", expressionToStoreOn.getProperty()); |
@@ -4277,7 +4280,7 @@ public void visitMethodCallExpression(MethodCallExpression call) { |
4277 | 4280 | if (!mn.isEmpty() |
4278 | 4281 | // GRECLIPSE add -- GROOVY-7890 |
4279 | 4282 | && currentReceiver.getData() == null |
4280 | | - && (typeCheckingContext.isInStaticContext || (receiverType.getModifiers() & Opcodes.ACC_STATIC) != 0) |
| 4283 | + && (typeCheckingContext.isInStaticContext || Modifier.isStatic(receiverType.getModifiers())) |
4281 | 4284 | && (call.isImplicitThis() || (objectExpression instanceof VariableExpression && ((VariableExpression) objectExpression).isThisExpression()))) { |
4282 | 4285 | // we create separate method lists just to be able to print out |
4283 | 4286 | // a nice error message to the user |
@@ -4347,7 +4350,7 @@ public void visitMethodCallExpression(MethodCallExpression call) { |
4347 | 4350 | addStaticTypeError("Non static method " + owner.getName() + "#" + directMethodCallCandidate.getName() + " cannot be called from static context", call); |
4348 | 4351 | } |
4349 | 4352 | // GRECLIPSE add -- GROOVY-10341 |
4350 | | - else if (directMethodCallCandidate.isAbstract() && objectExpression instanceof VariableExpression && ((VariableExpression) objectExpression).isSuperExpression()) |
| 4353 | + else if (directMethodCallCandidate.isAbstract() && isSuperExpression(objectExpression)) |
4351 | 4354 | addStaticTypeError("Abstract method " + toMethodParametersString(directMethodCallCandidate.getName(), extractTypesFromParameters(directMethodCallCandidate.getParameters())) + " cannot be called directly", call); |
4352 | 4355 | // GRECLIPSE end |
4353 | 4356 | if (chosenReceiver == null) { |
@@ -5001,9 +5004,9 @@ protected boolean checkCast(final ClassNode targetType, final Expression source) |
5001 | 5004 | // char c = (char) ... |
5002 | 5005 | } else if (sourceIsNull && isPrimitiveType(targetType) && !boolean_TYPE.equals(targetType)) { |
5003 | 5006 | return false; |
5004 | | - } else if ((expressionType.getModifiers() & Opcodes.ACC_FINAL) == 0 && targetType.isInterface()) { |
| 5007 | + } else if (!Modifier.isFinal(expressionType.getModifiers()) && targetType.isInterface()) { |
5005 | 5008 | return true; |
5006 | | - } else if ((targetType.getModifiers() & Opcodes.ACC_FINAL) == 0 && expressionType.isInterface()) { |
| 5009 | + } else if (!Modifier.isFinal(targetType.getModifiers()) && expressionType.isInterface()) { |
5007 | 5010 | return true; |
5008 | 5011 | } else if (!isAssignableTo(targetType, expressionType) && !implementsInterfaceOrIsSubclassOf(expressionType, targetType)) { |
5009 | 5012 | return false; |
@@ -6003,7 +6006,7 @@ protected ClassNode getType(final ASTNode exp) { |
6003 | 6006 | if (variable instanceof FieldNode) { |
6004 | 6007 | ClassNode fieldType = variable.getOriginType(); |
6005 | 6008 | if (isUsingGenericsOrIsArrayUsingGenerics(fieldType)) { |
6006 | | - boolean isStatic = (variable.getModifiers() & Opcodes.ACC_STATIC) != 0; |
| 6009 | + boolean isStatic = Modifier.isStatic(variable.getModifiers()); |
6007 | 6010 | ClassNode thisType = typeCheckingContext.getEnclosingClassNode(), declType = ((FieldNode) variable).getDeclaringClass(); |
6008 | 6011 | Map<GenericsTypeName, GenericsType> placeholders = resolvePlaceHoldersFromDeclaration(thisType, declType, null, isStatic); |
6009 | 6012 |
|
|
0 commit comments