-
Notifications
You must be signed in to change notification settings - Fork 913
Fix invalid element references during completion resolution using ElementHandle which has additional text edits #9005
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -549,6 +549,7 @@ public Completion createThisOrSuperConstructorItem(CompilationInfo info, Executa | |
| @Override | ||
| public Completion createOverrideMethodItem(CompilationInfo info, ExecutableElement elem, ExecutableType type, int substitutionOffset, boolean implement) { | ||
| Completion item = createExecutableItem(info, elem, type, substitutionOffset, null, false, false, false, false, false, -1, false); | ||
| ElementHandle<ExecutableElement> elemHandle = ElementHandle.create(elem); | ||
| CompletionCollector.Builder builder = CompletionCollector.newBuilder(item.getLabel()) | ||
| .kind(elementKind2CompletionItemKind(elem.getKind())) | ||
| .labelDetail(String.format("%s - %s", item.getLabelDetail(), implement ? "implement" : "override")) | ||
|
|
@@ -558,16 +559,21 @@ public Completion createOverrideMethodItem(CompilationInfo info, ExecutableEleme | |
| .textEdit(new TextEdit(substitutionOffset, substitutionOffset, EMPTY)) | ||
| .additionalTextEdits(() -> modify2TextEdits(JavaSource.forFileObject(info.getFileObject()), wc -> { | ||
| wc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); | ||
| ExecutableElement currentElem = elemHandle.resolve(wc); | ||
| if (currentElem == null) { | ||
| //cannot resolve? | ||
| return ; | ||
| } | ||
| TreePath tp = wc.getTreeUtilities().pathFor(substitutionOffset); | ||
| if (implement) { | ||
| GeneratorUtils.generateAbstractMethodImplementation(wc, tp, elem, substitutionOffset); | ||
| GeneratorUtils.generateAbstractMethodImplementation(wc, tp, currentElem, substitutionOffset); | ||
| } else { | ||
| GeneratorUtils.generateMethodOverride(wc, tp, elem, substitutionOffset); | ||
| GeneratorUtils.generateMethodOverride(wc, tp, currentElem, substitutionOffset); | ||
| } | ||
| })); | ||
| ElementHandle<ExecutableElement> handle = SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name()) ? ElementHandle.create(elem) : null; | ||
| if (handle != null) { | ||
| builder.documentation(getDocumentation(doc, offset, handle)); | ||
|
|
||
| if (SUPPORTED_ELEMENT_KINDS.contains(elem.getKind().name())) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the |
||
| builder.documentation(getDocumentation(doc, offset, elemHandle)); | ||
| } | ||
| return builder.build(); | ||
| } | ||
|
|
@@ -593,6 +599,7 @@ public Completion createGetterSetterMethodItem(CompilationInfo info, VariableEle | |
| sortParams.append(typeName); | ||
| } | ||
| labelDetail.append(") - generate"); | ||
| ElementHandle<VariableElement> elemHandle = ElementHandle.create(elem); | ||
| Builder builder = CompletionCollector.newBuilder(name) | ||
| .kind(Completion.Kind.Method) | ||
| .labelDetail(labelDetail.toString()) | ||
|
|
@@ -601,6 +608,10 @@ public Completion createGetterSetterMethodItem(CompilationInfo info, VariableEle | |
| .textEdit(new TextEdit(substitutionOffset, substitutionOffset, EMPTY)) | ||
| .additionalTextEdits(() -> modify2TextEdits(JavaSource.forFileObject(info.getFileObject()), wc -> { | ||
| wc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); | ||
| VariableElement currentElem = elemHandle.resolve(wc); | ||
| if (currentElem == null) { | ||
| return; | ||
| } | ||
| TreePath tp = wc.getTreeUtilities().pathFor(substitutionOffset); | ||
| if (TreeUtilities.CLASS_TREE_KINDS.contains(tp.getLeaf().getKind())) { | ||
| if (Utilities.inAnonymousOrLocalClass(tp)) { | ||
|
|
@@ -609,7 +620,7 @@ public Completion createGetterSetterMethodItem(CompilationInfo info, VariableEle | |
| TypeElement te = (TypeElement)wc.getTrees().getElement(tp); | ||
| if (te != null) { | ||
| GeneratorUtilities gu = GeneratorUtilities.get(wc); | ||
| MethodTree method = setter ? gu.createSetter(te, elem) : gu.createGetter(te, elem); | ||
| MethodTree method = setter ? gu.createSetter(te, currentElem) : gu.createGetter(te, currentElem); | ||
| ClassTree decl = GeneratorUtils.insertClassMember(wc, (ClassTree)tp.getLeaf(), method, substitutionOffset); | ||
| wc.rewrite(tp.getLeaf(), decl); | ||
| } | ||
|
|
@@ -870,7 +881,13 @@ public Completion createInitializeAllConstructorItem(CompilationInfo info, boole | |
| } | ||
| labelDetail.append(") - generate"); | ||
| sortParams.append(')'); | ||
| ElementHandle<?> parentPath = ElementHandle.create(parent); | ||
| ElementHandle<TypeElement> parentHandle = ElementHandle.create(parent); | ||
| ElementHandle<ExecutableElement> superConstructorHandle = superConstructor != null ? ElementHandle.create(superConstructor) : null; | ||
| List<ElementHandle<VariableElement>> fieldHandles = new ArrayList<>(); | ||
| for (VariableElement ve : fields) { | ||
| fieldHandles.add(ElementHandle.create(ve)); | ||
| } | ||
|
|
||
| return CompletionCollector.newBuilder(simpleName) | ||
| .kind(Completion.Kind.Constructor) | ||
| .labelDetail(labelDetail.toString()) | ||
|
|
@@ -879,23 +896,30 @@ public Completion createInitializeAllConstructorItem(CompilationInfo info, boole | |
| .textEdit(new TextEdit(substitutionOffset, substitutionOffset, EMPTY)) | ||
| .additionalTextEdits(() -> modify2TextEdits(JavaSource.forFileObject(info.getFileObject()), wc -> { | ||
| wc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED); | ||
| TypeElement currentParent = parentHandle.resolve(wc); | ||
| if (currentParent == null) { | ||
| return; | ||
| } | ||
| ExecutableElement currentSuperConstructor = superConstructorHandle != null ? superConstructorHandle.resolve(wc) : null; | ||
|
|
||
| TreePath tp = wc.getTreeUtilities().pathFor(substitutionOffset); | ||
| if (TreeUtilities.CLASS_TREE_KINDS.contains(tp.getLeaf().getKind())) { | ||
| Element currentType = wc.getTrees().getElement(tp); | ||
| ElementHandle<?> currentTypePath = | ||
| currentType != null ? ElementHandle.create(currentType) | ||
| : null; | ||
| if (Objects.equals(parentPath, currentTypePath)) { | ||
| if (Objects.equals(parentHandle, currentTypePath)) { | ||
| ArrayList<VariableElement> fieldElements = new ArrayList<>(); | ||
| for (VariableElement fieldElement : fields) { | ||
| for (ElementHandle<VariableElement> fieldHandle : fieldHandles) { | ||
| VariableElement fieldElement = fieldHandle.resolve(wc); | ||
| if (fieldElement != null && fieldElement.getKind().isField()) { | ||
| fieldElements.add((VariableElement)fieldElement); | ||
| } | ||
| } | ||
| ClassTree clazz = (ClassTree) tp.getLeaf(); | ||
| GeneratorUtilities gu = GeneratorUtilities.get(wc); | ||
| MethodTree ctor = isDefault ? gu.createDefaultConstructor(parent, fieldElements, superConstructor) | ||
| : gu.createConstructor(parent, fieldElements, superConstructor); | ||
| MethodTree ctor = isDefault ? gu.createDefaultConstructor(currentParent, fieldElements, currentSuperConstructor) | ||
| : gu.createConstructor(currentParent, fieldElements, currentSuperConstructor); | ||
| ClassTree decl = GeneratorUtils.insertClassMember(wc, clazz, ctor, substitutionOffset); | ||
| wc.rewrite(clazz, decl); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit - maybe remove this comment, as other places don't have it either. (Or add logging to this and other places.)