Skip to content

Fixing compilation errors after platform localization. Some refactoring - #54

Merged
VISTALL merged 1 commit into
consulo:masterfrom
unv-unv:compilation-fix
Oct 12, 2026
Merged

VISTALL merged 1 commit into
consulo:masterfrom
unv-unv:compilation-fix

Conversation

@unv-unv

@unv-unv unv-unv commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@unv-unv

unv-unv commented Oct 12, 2026

Copy link
Copy Markdown
Contributor Author

@claude review pr with inline comments

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @unv-unv's task in 1m 46s —— View job


PR #54 review

  • Gather context
  • Review diff
  • Post inline comments (review)
  • Summary

Most of this PR is a reformat plus a switch from String to LocalizeValue in ItemPresentation.getPresentableText(), ElementDescriptionProvider and PyParameterList.getPresentableText(boolean). That migration looks correct. I found no logic bugs, and the refactorings (pattern-matching instanceof, Ref → SimpleReference, read/write action annotations) keep the behaviour the same. I did not build the project.

Inline comments (each has a one-click suggestion unless noted)

  1. PyImportElementImpl.java:158: this uses LocalizeValue.localizeTODO(...) for a reference name, which is an identifier and never needs localization. It should be LocalizeValue.of(...), like the other presentations in this PR.
  2. PyStarImportElementImpl.java:94-113: the inner if (results.isEmpty()) can never be true, and the copy loop can be new ArrayList<>(results). The suggestion also uses the pattern-matching instanceof from iterateNames().
  3. PyStructureViewElement.java:280-288: the reformat left the three overlay = ... lines at the old indentation.
  4. PyNames.java:209 (no suggestion): UNNAMED_ELEMENT changes type from String to LocalizeValue in the public python-psi-api, which breaks third-party code that uses it. Also, PyElementNode still has its own hardcoded "<unnamed>".
  5. PyFunctionImpl.java:295 (nit): the line is about 150 characters; the suggestion wraps it.

Outside the diff (can't comment inline)

PyParameterList.getPresentableText(boolean) now returns LocalizeValue, but two callers still pass the result to StringBuilder.append(Object). That compiles silently and depends on LocalizeValue.toString() returning the text:

  • python-impl/.../projectView/PyElementNode.java:67
  • python-impl/.../codeInsight/imports/ImportCandidateHolder.java:142

Adding .get() at both places would make this explicit and not rely on toString(): getParameterList().getPresentableText(false).get().

Fix this →

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline review from Claude. Overall the migration to LocalizeValue looks right; a few points below. See the summary comment for two call sites outside the diff that are affected by the PyParameterList.getPresentableText signature change.

return getRefName("<none>");
}
public LocalizeValue getPresentableText() {
return LocalizeValue.localizeTODO(getRefName("<none>"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

localizeTODO marks text that should be localized later, but this is a reference name (an identifier), so it never needs localization. Every other presentation in this PR uses LocalizeValue.of(...) for identifiers (PyStarImportElementImpl, PyFileImpl, etc.), and using it here too keeps the TODO markers meaningful.

Suggested change
return LocalizeValue.localizeTODO(getRefName("<none>"));
return LocalizeValue.of(getRefName("<none>"));

Comment on lines +94 to +113
PsiElement source = PyUtil.turnDirIntoInit(importedFile);
if (source instanceof PyFile) {
PyFile sourceFile = (PyFile) source;
PyModuleType moduleType = new PyModuleType(sourceFile);
List<? extends RatedResolveResult> results = moduleType.resolveMember(
name,
null,
AccessDirection.READ,
PyResolveContext.defaultContext()
);
if (results != null && !results.isEmpty() && PyUtil.isStarImportableFrom(name, sourceFile)) {
if (results.isEmpty()) {
return Collections.emptyList();
}
List<RatedResolveResult> res = Lists.newArrayList();
for (RatedResolveResult result : results) {
res.add(result);
}
return res;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this method is already being refactored: the inner if (results.isEmpty()) can never be true because the outer condition already checks !results.isEmpty(). The copy loop can also be a plain new ArrayList<>(results). This change would also match the pattern-matching instanceof you used in iterateNames() above. Behaviour stays the same.

Suggested change
PsiElement source = PyUtil.turnDirIntoInit(importedFile);
if (source instanceof PyFile) {
PyFile sourceFile = (PyFile) source;
PyModuleType moduleType = new PyModuleType(sourceFile);
List<? extends RatedResolveResult> results = moduleType.resolveMember(
name,
null,
AccessDirection.READ,
PyResolveContext.defaultContext()
);
if (results != null && !results.isEmpty() && PyUtil.isStarImportableFrom(name, sourceFile)) {
if (results.isEmpty()) {
return Collections.emptyList();
}
List<RatedResolveResult> res = Lists.newArrayList();
for (RatedResolveResult result : results) {
res.add(result);
}
return res;
}
if (PyUtil.turnDirIntoInit(importedFile) instanceof PyFile sourceFile) {
PyModuleType moduleType = new PyModuleType(sourceFile);
List<? extends RatedResolveResult> results = moduleType.resolveMember(
name,
null,
AccessDirection.READ,
PyResolveContext.defaultContext()
);
if (results != null && !results.isEmpty() && PyUtil.isStarImportableFrom(name, sourceFile)) {
return new ArrayList<>(results);
}
}

(You'd need to add import java.util.ArrayList;. The com.google.common.collect.Lists import then becomes unused.)

Comment on lines +280 to +288
if (myVisibility == Visibility.PRIVATE || myVisibility == Visibility.PROTECTED) {
overlay = PythonIcons.Python.Nodes.Lock;
}
else if (myVisibility == Visibility.PREDEFINED) {
}
else if (myVisibility == Visibility.PREDEFINED) {
overlay = PythonIcons.Python.Nodes.Cyan_dot;
}
else if (myVisibility == Visibility.INVISIBLE) {
}
else if (myVisibility == Visibility.INVISIBLE) {
overlay = PythonIcons.Python.Nodes.Red_inv_triangle;
}
if (overlay != null) {
iconDescriptor.addLayerIcon(overlay);
}
return iconDescriptor.toIcon();
}
}
};
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reformat skipped these three overlay = ... lines, so they're still at the old indentation.

Suggested change
if (myVisibility == Visibility.PRIVATE || myVisibility == Visibility.PROTECTED) {
overlay = PythonIcons.Python.Nodes.Lock;
}
else if (myVisibility == Visibility.PREDEFINED) {
}
else if (myVisibility == Visibility.PREDEFINED) {
overlay = PythonIcons.Python.Nodes.Cyan_dot;
}
else if (myVisibility == Visibility.INVISIBLE) {
}
else if (myVisibility == Visibility.INVISIBLE) {
overlay = PythonIcons.Python.Nodes.Red_inv_triangle;
}
if (overlay != null) {
iconDescriptor.addLayerIcon(overlay);
}
return iconDescriptor.toIcon();
}
}
};
}
}
if (myVisibility == Visibility.PRIVATE || myVisibility == Visibility.PROTECTED) {
overlay = PythonIcons.Python.Nodes.Lock;
}
else if (myVisibility == Visibility.PREDEFINED) {
overlay = PythonIcons.Python.Nodes.Cyan_dot;
}
else if (myVisibility == Visibility.INVISIBLE) {
overlay = PythonIcons.Python.Nodes.Red_inv_triangle;
}

public static final String UNKNOWN_TYPE = "Any";

public static final String UNNAMED_ELEMENT = "<unnamed>";
public static final LocalizeValue UNNAMED_ELEMENT = LocalizeValue.localizeTODO("<unnamed>");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the type of a public constant in python-psi-api from String to LocalizeValue. That's a source/binary break for any third-party code that uses PyNames.UNNAMED_ELEMENT. Inside this repo, all usages are updated. Two optional follow-ups:

  • PyElementNode.updateImpl (python-impl/.../projectView/PyElementNode.java:65) still hardcodes "<unnamed>". It could use PyNames.UNNAMED_ELEMENT.get() so the literal lives in one place.
  • If this is meant to be localized for real, consider adding a proper key to the Python localize YAML instead of localizeTODO.

public String getPresentableText() {
return notNullize(getName(), PyNames.UNNAMED_ELEMENT) + getParameterList().getPresentableText(true);
public LocalizeValue getPresentableText() {
return LocalizeValue.join(LocalizeValue.ofNullable(getName()).orIfEmpty(PyNames.UNNAMED_ELEMENT), getParameterList().getPresentableText(true));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this line is about 150 characters. Wrapping it would match the multi-line argument style used elsewhere in this PR.

Suggested change
return LocalizeValue.join(LocalizeValue.ofNullable(getName()).orIfEmpty(PyNames.UNNAMED_ELEMENT), getParameterList().getPresentableText(true));
return LocalizeValue.join(
LocalizeValue.ofNullable(getName()).orIfEmpty(PyNames.UNNAMED_ELEMENT),
getParameterList().getPresentableText(true)
);

@VISTALL
VISTALL merged commit cc82d85 into consulo:master Oct 12, 2026
1 check failed
@unv-unv
unv-unv deleted the compilation-fix branch October 12, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants