|
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