From df710afc6582fa330d37734f806b6a03345816be Mon Sep 17 00:00:00 2001 From: David Thompson Date: Tue, 22 Oct 2024 15:39:29 -0400 Subject: [PATCH] Fix some NPEs in completion Signed-off-by: David Thompson --- .../codeassist/DOMCompletionEngine.java | 54 +++++++++++-------- .../DOMCompletionEngineBuilder.java | 4 +- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/DOMCompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/DOMCompletionEngine.java index 15b21645c98..95130f4839d 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/DOMCompletionEngine.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/DOMCompletionEngine.java @@ -240,7 +240,11 @@ public void run() { if (context instanceof FieldAccess fieldAccess) { statementLikeKeywords(); - processMembers(fieldAccess, fieldAccess.getExpression().resolveTypeBinding(), specificCompletionBindings, false); + + ITypeBinding fieldAccessType = fieldAccess.getExpression().resolveTypeBinding(); + if (fieldAccessType != null) { + processMembers(fieldAccess, fieldAccess.getExpression().resolveTypeBinding(), specificCompletionBindings, false); + } if (specificCompletionBindings.stream().findAny().isPresent()) { specificCompletionBindings.stream() .filter(binding -> this.pattern.matchesName(this.prefix.toCharArray(), binding.getName().toCharArray())) @@ -269,12 +273,15 @@ public void run() { } // complete name ITypeBinding type = expression.resolveTypeBinding(); - processMembers(expression, type, specificCompletionBindings, false); - specificCompletionBindings.stream() - .filter(binding -> this.pattern.matchesName(this.prefix.toCharArray(), binding.getName().toCharArray())) - .filter(IMethodBinding.class::isInstance) - .map(binding -> toProposal(binding)) - .forEach(this.requestor::accept); + if (type != null) { + processMembers(expression, type, specificCompletionBindings, false); + specificCompletionBindings.stream() + .filter(binding -> this.pattern.matchesName(this.prefix.toCharArray(), binding.getName().toCharArray())) + .filter(IMethodBinding.class::isInstance) + .map(binding -> toProposal(binding)) + .forEach(this.requestor::accept); + } + suggestDefaultCompletions = false; } // else complete parameters, get back to default } @@ -892,20 +899,23 @@ private CompletionProposal toProposal(IBinding binding, String completion) { res.setSignature( Signature.createTypeSignature(variableBinding.getType().getQualifiedName().toCharArray(), true) .toCharArray()); - res.setReceiverSignature( - variableBinding.isField() - ? Signature - .createTypeSignature( - variableBinding.getDeclaringClass().getQualifiedName().toCharArray(), true) - .toCharArray() - : new char[] {}); - res.setDeclarationSignature( - variableBinding.isField() - ? Signature - .createTypeSignature( - variableBinding.getDeclaringClass().getQualifiedName().toCharArray(), true) - .toCharArray() - : new char[] {}); + if (variableBinding.isField()) { + ITypeBinding declaringClass = variableBinding.getDeclaringClass(); + if (declaringClass != null) { + char[] declSignature = Signature + .createTypeSignature( + variableBinding.getDeclaringClass().getQualifiedName().toCharArray(), true) + .toCharArray(); + res.setReceiverSignature(declSignature); + res.setDeclarationSignature(declSignature); + } else { + res.setReceiverSignature(new char[0]); + res.setDeclarationSignature(new char[0]); + } + } else { + res.setReceiverSignature(new char[0]); + res.setDeclarationSignature(new char[0]); + } } else if (kind == CompletionProposal.TYPE_REF) { var typeBinding = (ITypeBinding) binding; res.setSignature( @@ -1067,7 +1077,7 @@ private int computeRelevanceForExpectingType(ITypeBinding proposalType){ if(Objects.equals(expectedType.getQualifiedName(), proposalType.getQualifiedName())) { return RelevanceConstants.R_EXACT_EXPECTED_TYPE; - } else if (proposalType.getPackage().isUnnamed()) { + } else if (proposalType.getPackage() != null && proposalType.getPackage().isUnnamed()) { return RelevanceConstants.R_PACKAGE_EXPECTED_TYPE; } relevance = RelevanceConstants.R_EXPECTED_TYPE; diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/DOMCompletionEngineBuilder.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/DOMCompletionEngineBuilder.java index 85489da2ca5..c8f790db76d 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/DOMCompletionEngineBuilder.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/DOMCompletionEngineBuilder.java @@ -102,7 +102,7 @@ static void createMethod(IMethodBinding methodBinding, StringBuilder completion) static void createType(ITypeBinding type, StringBuilder completion) { if (type.isWildcardType() || type.isIntersectionType()) { completion.append('?'); - if (type.isUpperbound()) { + if (type.isUpperbound() && type.getBound() != null) { completion.append(' '); completion.append(EXTENDS); completion.append(' '); @@ -115,7 +115,7 @@ static void createType(ITypeBinding type, StringBuilder completion) { createType(bound, completion); } } - } else { + } else if (type.getBound() != null) { completion.append(' '); completion.append(SUPER); completion.append(' ');