Skip to content

Commit

Permalink
Fix for NPE
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Nov 11, 2019
1 parent 3239180 commit aa5056d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3802,13 +3802,25 @@ public void visitTryCatchFinally(final TryCatchStatement statement) {
}

protected void storeType(Expression exp, ClassNode cn) {
/* GRECLIPSE edit
if (exp instanceof VariableExpression && ((VariableExpression) exp).isClosureSharedVariable() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
} else if (exp instanceof MethodCallExpression && ((MethodCallExpression) exp).isSafe() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
} else if (exp instanceof PropertyExpression && ((PropertyExpression) exp).isSafe() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
}
*/
if (cn != null && isPrimitiveType(cn)) {
if (exp instanceof VariableExpression && ((VariableExpression) exp).isClosureSharedVariable()) {
cn = getWrapper(cn);
} else if (exp instanceof MethodCallExpression && ((MethodCallExpression) exp).isSafe()) {
cn = getWrapper(cn);
} else if (exp instanceof PropertyExpression && ((PropertyExpression) exp).isSafe()) {
cn = getWrapper(cn);
}
}
// GRECLIPSE end
if (cn == UNKNOWN_PARAMETER_TYPE) {
// this can happen for example when "null" is used in an assignment or a method parameter.
// In that case, instead of storing the virtual type, we must "reset" type information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4043,13 +4043,25 @@ public void visitTryCatchFinally(final TryCatchStatement statement) {
}

protected void storeType(Expression exp, ClassNode cn) {
/* GRECLIPSE edit
if (exp instanceof VariableExpression && ((VariableExpression) exp).isClosureSharedVariable() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
} else if (exp instanceof MethodCallExpression && ((MethodCallExpression) exp).isSafe() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
} else if (exp instanceof PropertyExpression && ((PropertyExpression) exp).isSafe() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
}
*/
if (cn != null && isPrimitiveType(cn)) {
if (exp instanceof VariableExpression && ((VariableExpression) exp).isClosureSharedVariable()) {
cn = getWrapper(cn);
} else if (exp instanceof MethodCallExpression && ((MethodCallExpression) exp).isSafe()) {
cn = getWrapper(cn);
} else if (exp instanceof PropertyExpression && ((PropertyExpression) exp).isSafe()) {
cn = getWrapper(cn);
}
}
// GRECLIPSE end
if (cn == UNKNOWN_PARAMETER_TYPE) {
// this can happen for example when "null" is used in an assignment or a method parameter.
// In that case, instead of storing the virtual type, we must "reset" type information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -569,18 +569,15 @@ private void checkOrMarkPrivateAccess(Expression source, MethodNode mn) {
private void checkSuperCallFromClosure(Expression call, MethodNode directCallTarget) {
if (call instanceof MethodCallExpression && typeCheckingContext.getEnclosingClosure() != null) {
Expression objectExpression = ((MethodCallExpression) call).getObjectExpression();
if (objectExpression instanceof VariableExpression) {
VariableExpression var = (VariableExpression) objectExpression;
if (var.isSuperExpression()) {
ClassNode current = typeCheckingContext.getEnclosingClassNode();
LinkedList<MethodNode> list = current.getNodeMetaData(SUPER_MOP_METHOD_REQUIRED);
if (list == null) {
list = new LinkedList<MethodNode>();
current.putNodeMetaData(SUPER_MOP_METHOD_REQUIRED, list);
}
list.add(directCallTarget);
call.putNodeMetaData(SUPER_MOP_METHOD_REQUIRED, current);
if (isSuperExpression(objectExpression)) {
ClassNode current = typeCheckingContext.getEnclosingClassNode();
LinkedList<MethodNode> list = current.getNodeMetaData(SUPER_MOP_METHOD_REQUIRED);
if (list == null) {
list = new LinkedList<MethodNode>();
current.putNodeMetaData(SUPER_MOP_METHOD_REQUIRED, list);
}
list.add(directCallTarget);
call.putNodeMetaData(SUPER_MOP_METHOD_REQUIRED, current);
}
}
}
Expand Down Expand Up @@ -2266,15 +2263,12 @@ public void visitConstructorCallExpression(ConstructorCallExpression call) {
ClassNode[] args = getArgumentTypes(argumentList);
if (args.length > 0 &&
typeCheckingContext.getEnclosingClosure() != null &&
argumentList.getExpression(0) instanceof VariableExpression &&
((VariableExpression) argumentList.getExpression(0)).isThisExpression() &&
call.getType() instanceof InnerClassNode &&
call.getType().getOuterClass().equals(args[0]) &&
isThisExpression(argumentList.getExpression(0)) &&
args[0].equals(call.getType().getOuterClass()) &&
!call.getType().isStaticClass()) {
args[0] = CLOSURE_TYPE;
}


MethodNode node;
if (looksLikeNamedArgConstructor(receiver, args)
&& findMethod(receiver, "<init>", DefaultGroovyMethods.init(args)).size() == 1
Expand Down Expand Up @@ -3360,7 +3354,7 @@ public void visitMethodCallExpression(MethodCallExpression call) {
boolean callArgsVisited = false;
if (isCallOnClosure) {
// this is a closure.call() call
if (objectExpression == VariableExpression.THIS_EXPRESSION) {
if (isThisExpression(objectExpression)) {
// isClosureCall() check verified earlier that a field exists
FieldNode field = typeCheckingContext.getEnclosingClassNode().getDeclaredField(name);
GenericsType[] genericsTypes = field.getType().getGenericsTypes();
Expand Down Expand Up @@ -3436,8 +3430,8 @@ public void visitMethodCallExpression(MethodCallExpression call) {
// if we are not in a static context but the current receiver is a static class, we must
// ensure that all methods are either static or declared by the current receiver or a superclass
if (!mn.isEmpty()
&& (typeCheckingContext.isInStaticContext || (receiverType.getModifiers() & Opcodes.ACC_STATIC) != 0)
&& (call.isImplicitThis() || (objectExpression instanceof VariableExpression && ((VariableExpression) objectExpression).isThisExpression()))) {
&& (call.isImplicitThis() || isThisExpression(objectExpression))
&& (typeCheckingContext.isInStaticContext || (receiverType.getModifiers() & Opcodes.ACC_STATIC) != 0)) {
// we create separate method lists just to be able to print out
// a nice error message to the user
// a method is accessible if it is static, or if we are not in a static context and it is
Expand Down Expand Up @@ -3500,15 +3494,10 @@ public void visitMethodCallExpression(MethodCallExpression call) {
}

ClassNode returnType = getType(directMethodCallCandidate);

if (isUsingGenericsOrIsArrayUsingGenerics(returnType)) {
visitMethodCallArguments(chosenReceiver.getType(), argumentList, true, directMethodCallCandidate);
ClassNode irtg = inferReturnTypeGenerics(
chosenReceiver.getType(),
directMethodCallCandidate,
callArguments,
call.getGenericsTypes());
returnType = irtg != null && implementsInterfaceOrIsSubclassOf(irtg, returnType) ? irtg : returnType;
ClassNode irtg = inferReturnTypeGenerics(chosenReceiver.getType(), directMethodCallCandidate, callArguments, call.getGenericsTypes());
returnType = (irtg != null && implementsInterfaceOrIsSubclassOf(irtg, returnType) ? irtg : returnType);
callArgsVisited = true;
}
if (directMethodCallCandidate == GET_DELEGATE && typeCheckingContext.getEnclosingClosure() != null) {
Expand Down Expand Up @@ -3568,7 +3557,7 @@ && isNumberType(getType(argumentList.getExpression(0)))) {
if (mn != null) {
List<Expression> argExpressions = argumentList.getExpressions();
Parameter[] parameters = mn.getParameters();
for (int i = 0; i < argExpressions.size() && i < parameters.length; i++) {
for (int i = 0; i < argExpressions.size() && i < parameters.length; i += 1) {
Expression arg = argExpressions.get(i);
ClassNode pType = parameters[i].getType();
ClassNode aType = getType(arg);
Expand Down Expand Up @@ -3813,7 +3802,7 @@ protected void storeTargetMethod(final Expression call, final MethodNode directM

protected boolean isClosureCall(final String name, final Expression objectExpression, final Expression arguments) {
if (objectExpression instanceof ClosureExpression && ("call".equals(name) || "doCall".equals(name))) return true;
if (objectExpression == VariableExpression.THIS_EXPRESSION) {
if (isThisExpression(objectExpression)) {
FieldNode fieldNode = typeCheckingContext.getEnclosingClassNode().getDeclaredField(name);
if (fieldNode != null) {
ClassNode type = fieldNode.getType();
Expand Down Expand Up @@ -4212,13 +4201,25 @@ public void visitTryCatchFinally(final TryCatchStatement statement) {
}

protected void storeType(Expression exp, ClassNode cn) {
/* GRECLIPSE edit
if (exp instanceof VariableExpression && ((VariableExpression) exp).isClosureSharedVariable() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
} else if (exp instanceof MethodCallExpression && ((MethodCallExpression) exp).isSafe() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
} else if (exp instanceof PropertyExpression && ((PropertyExpression) exp).isSafe() && isPrimitiveType(cn)) {
cn = getWrapper(cn);
}
*/
if (cn != null && isPrimitiveType(cn)) {
if (exp instanceof VariableExpression && ((VariableExpression) exp).isClosureSharedVariable()) {
cn = getWrapper(cn);
} else if (exp instanceof MethodCallExpression && ((MethodCallExpression) exp).isSafe()) {
cn = getWrapper(cn);
} else if (exp instanceof PropertyExpression && ((PropertyExpression) exp).isSafe()) {
cn = getWrapper(cn);
}
}
// GRECLIPSE end
if (cn == UNKNOWN_PARAMETER_TYPE) {
// this can happen for example when "null" is used in an assignment or a method parameter.
// In that case, instead of storing the virtual type, we must "reset" type information
Expand Down Expand Up @@ -4847,15 +4848,14 @@ protected ClassNode getType(final ASTNode exp) {
return node;
}
if (exp instanceof VariableExpression) {
final VariableExpression vexp = (VariableExpression) exp;
VariableExpression vexp = (VariableExpression) exp;
ClassNode selfTrait = isTraitSelf(vexp);
if (selfTrait != null) return makeSelf(selfTrait);
if (vexp == VariableExpression.THIS_EXPRESSION) return makeThis();
if (vexp == VariableExpression.SUPER_EXPRESSION) return makeSuper();
final Variable variable = vexp.getAccessedVariable();
if (vexp.isThisExpression()) return makeThis();
if (vexp.isSuperExpression()) return makeSuper();
Variable variable = vexp.getAccessedVariable();
if (variable instanceof FieldNode) {
FieldNode fieldNode = (FieldNode) variable;

checkOrMarkPrivateAccess(vexp, fieldNode, isLHSOfEnclosingAssignment(vexp));
return getType(fieldNode);
}
Expand Down Expand Up @@ -5089,6 +5089,14 @@ protected static boolean isNullConstant(final Expression expression) {
return expression instanceof ConstantExpression && ((ConstantExpression) expression).isNullExpression();
}

protected static boolean isThisExpression(final Expression expression) {
return expression instanceof VariableExpression && ((VariableExpression) expression).isThisExpression();
}

protected static boolean isSuperExpression(final Expression expression) {
return expression instanceof VariableExpression && ((VariableExpression) expression).isSuperExpression();
}

protected ClassNode inferMapExpressionType(final MapExpression map) {
ClassNode mapType = LINKEDHASHMAP_CLASSNODE.getPlainNodeReference();
List<MapEntryExpression> entryExpressions = map.getMapEntryExpressions();
Expand Down

0 comments on commit aa5056d

Please sign in to comment.