Skip to content

Commit

Permalink
5.12: symbols references
Browse files Browse the repository at this point in the history
  • Loading branch information
smklimenko committed Nov 29, 2024
1 parent fd7951e commit 4fe4ac2
Show file tree
Hide file tree
Showing 21 changed files with 531 additions and 169 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# KdbInsideBrains Changelog

## [5.12.0]

### Added

- Symbol is parsed as a variable if used in any 'set' expression, like: _`myvariable set ..._ or _set[`myvariable;...]_
- Symbols declared as a variable in any form support cross-links to/from the declaration and can be renamed
- Structure view performance improved

## [5.11.1]

### Fixed
Expand Down
34 changes: 22 additions & 12 deletions src/main/java/icons/KdbIcons.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.intellij.icons.AllIcons;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.IconManager;
import com.intellij.ui.LayeredIcon;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
Expand All @@ -13,11 +12,16 @@ public final class KdbIcons {
return IconLoader.getIcon(path, KdbIcons.class);
}

private static @NotNull LayeredIcon lineIcons(@NotNull Icon icon1, @NotNull Icon icon2) {
LayeredIcon icon = new LayeredIcon(2);
icon.setIcon(icon1, 0, 0, 0);
icon.setIcon(icon2, 1, icon1.getIconWidth(), 0);
return icon;
private static @NotNull Icon row(@NotNull Icon icon1, @NotNull Icon icon2) {
return IconManager.getInstance().createRowIcon(icon1, icon2);
// LayeredIcon icon = new LayeredIcon(2);
// icon.setIcon(icon1, 0, 0, 0);
// icon.setIcon(icon2, 1, icon1.getIconWidth(), 0);
// return icon;
}

private static @NotNull Icon layer(@NotNull Icon icon1, @NotNull Icon icon2) {
return IconManager.getInstance().createLayered(icon1, icon2);
}

public static final class Main {
Expand All @@ -35,7 +39,7 @@ public static final class Main {
public static final class Scope {
public static final @NotNull Icon Icon = AllIcons.Ide.LocalScope;
public static final @NotNull Icon Local = AllIcons.Ide.LocalScope;
public static final @NotNull Icon Shared = IconManager.getInstance().createLayered(AllIcons.Ide.LocalScope, AllIcons.Nodes.Shared);
public static final @NotNull Icon Shared = layer(AllIcons.Ide.LocalScope, AllIcons.Nodes.Shared);
}

public static final class Chart {
Expand Down Expand Up @@ -108,11 +112,14 @@ public static final class Console {
}

public static final class Node {
public static final @NotNull Icon PublicItem = AllIcons.Nodes.C_public;
public static final @NotNull Icon PrivateItem = AllIcons.Nodes.C_private;

public static final @NotNull Icon Package = AllIcons.Nodes.Folder;
public static final @NotNull Icon Instance = load("/org/kdb/inside/brains/icons/instance.svg");

public static final @NotNull Icon InstanceQueryRunning = lineIcons(Instance, AllIcons.Actions.Execute);
public static final @NotNull Icon InstanceQueryCancelled = lineIcons(Instance, AllIcons.Actions.Suspend);
public static final @NotNull Icon InstanceQueryRunning = row(Instance, AllIcons.Actions.Execute);
public static final @NotNull Icon InstanceQueryCancelled = row(Instance, AllIcons.Actions.Suspend);

public static final @NotNull Icon NewPackage = AllIcons.Actions.NewFolder;
public static final @NotNull Icon NewInstance = load("/org/kdb/inside/brains/icons/newInstance.svg");
Expand All @@ -123,22 +130,25 @@ public static final class Node {
public static final @NotNull Icon Context = load("/org/kdb/inside/brains/icons/nodes/context.svg");
public static final @NotNull Icon Symbol = AllIcons.Nodes.Static;
public static final @NotNull Icon Lambda = AllIcons.Nodes.Lambda;
public static final @NotNull Icon LambdaPublic = row(Lambda, Node.PublicItem);
public static final @NotNull Icon LambdaPrivate = row(Lambda, Node.PrivateItem);
public static final @NotNull Icon Variable = AllIcons.Nodes.Variable;
public static final @NotNull Icon VariablePublic = row(Variable, Node.PublicItem);
public static final @NotNull Icon VariablePrivate = row(Variable, Node.PrivateItem);
public static final @NotNull Icon Parameter = AllIcons.Nodes.Parameter;
public static final @NotNull Icon Function = AllIcons.Nodes.Function;
public static final @NotNull Icon Keyword = AllIcons.Nodes.Constant;
public static final @NotNull Icon Namespace = AllIcons.Nodes.Package;

public static final @NotNull Icon Table = AllIcons.Nodes.DataTables;
public static final @NotNull Icon TablePublic = row(Table, Node.PublicItem);
public static final @NotNull Icon TablePrivate = row(Table, Node.PrivateItem);
public static final @NotNull Icon TableKeyColumn = load("/org/kdb/inside/brains/icons/nodes/keyColumn.svg");
public static final @NotNull Icon TableValueColumn = load("/org/kdb/inside/brains/icons/nodes/valueColumn.svg");

public static final @NotNull Icon ChangeColor = AllIcons.Actions.Colors;
public static final @NotNull Icon ShowConnectionFilter = AllIcons.Actions.Show;

public static final @NotNull Icon PublicItem = AllIcons.Nodes.C_public;
public static final @NotNull Icon PrivateItem = AllIcons.Nodes.C_private;

public static final @NotNull Icon SystemNamespaces = AllIcons.Nodes.Private;

public static final @NotNull Icon GroupTables = load("/org/kdb/inside/brains/icons/nodes/groupTables.svg");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.indexing.FindSymbolParameters;
import org.jetbrains.annotations.NotNull;
import org.kdb.inside.brains.psi.index.DeclarationRef;
import org.kdb.inside.brains.psi.index.QIndexService;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

public final class QChooseByNameContributor implements ChooseByNameContributor {
@Override
Expand All @@ -26,7 +28,7 @@ public final class QChooseByNameContributor implements ChooseByNameContributor {
@Override
public NavigationItem @NotNull [] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) {
final FindSymbolParameters simple = FindSymbolParameters.simple(project, includeNonProjectItems);
final Collection<? extends NavigationItem> result = QIndexService.getInstance(project).getDeclarations(name, simple.getSearchScope());
return result.isEmpty() ? NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY : result.toArray(NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY);
final Collection<DeclarationRef> declarations = QIndexService.getInstance(project).getDeclarations(name, simple.getSearchScope());
return declarations.isEmpty() ? NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY : declarations.stream().map(DeclarationRef::getNavigationItem).filter(Objects::nonNull).toArray(NavigationItem[]::new);
}
}
32 changes: 17 additions & 15 deletions src/main/java/org/kdb/inside/brains/psi/QIconProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import com.intellij.ide.IconProvider;
import com.intellij.openapi.project.DumbAware;
import com.intellij.psi.PsiElement;
import com.intellij.ui.IconManager;
import com.intellij.ui.icons.RowIcon;
import com.intellij.util.BitUtil;
import icons.KdbIcons;
import org.jetbrains.annotations.NotNull;
Expand All @@ -21,9 +19,9 @@ public static Icon getColumnIcon(@NotNull QTableColumn column) {

@Override
public @Nullable Icon getIcon(@NotNull PsiElement element, int flags) {
final boolean visibility = BitUtil.isSet(flags, ICON_FLAG_VISIBILITY);

if (element instanceof QImport) {
if (element instanceof QFile) {
return KdbIcons.Node.File;
} else if (element instanceof QImport) {
return KdbIcons.Node.Import;
} else if (element instanceof QCommand) {
return KdbIcons.Node.Command;
Expand All @@ -36,7 +34,7 @@ public static Icon getColumnIcon(@NotNull QTableColumn column) {
} else if (element instanceof QLambdaExpr) {
return KdbIcons.Node.Lambda;
} else if (element instanceof QAssignmentExpr assignment) {
return getAssignmentIcon(assignment, visibility);
return getAssignmentIcon(assignment, BitUtil.isSet(flags, ICON_FLAG_VISIBILITY));
} else if (element instanceof QVarDeclaration declaration) {
return getIcon(declaration.getParent(), flags);
}
Expand All @@ -49,17 +47,12 @@ private Icon getAssignmentIcon(QAssignmentExpr assignment, boolean visibility) {
return null;
}

Icon i = getExpressionIcon(expression);
if (visibility) {
final RowIcon icon = IconManager.getInstance().createLayeredIcon(assignment, i, 0);
icon.setIcon(getVisibilityIcon(assignment), 1);
return icon;
final boolean global = QPsiUtil.isGlobalDeclaration(assignment);
return getExpressionIcon(expression, global);
} else {
return getExpressionIcon(expression);
}
return i;
}

private Icon getVisibilityIcon(QAssignmentExpr assignment) {
return QPsiUtil.isGlobalDeclaration(assignment) ? KdbIcons.Node.PublicItem : KdbIcons.Node.PrivateItem;
}

private Icon getExpressionIcon(QExpression expression) {
Expand All @@ -70,4 +63,13 @@ private Icon getExpressionIcon(QExpression expression) {
}
return KdbIcons.Node.Variable;
}

private Icon getExpressionIcon(QExpression expression, boolean global) {
if (expression instanceof QLambdaExpr) {
return global ? KdbIcons.Node.LambdaPublic : KdbIcons.Node.LambdaPrivate;
} else if (expression instanceof QTableExpr) {
return global ? KdbIcons.Node.TablePublic : KdbIcons.Node.TablePrivate;
}
return global ? KdbIcons.Node.VariablePublic : KdbIcons.Node.VariablePrivate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.kdb.inside.brains.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import icons.KdbIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.kdb.inside.brains.psi.QPsiUtil;
import org.kdb.inside.brains.psi.QSymbol;

import java.util.Optional;

public class QSymbolElementImpl extends QPsiElementImpl implements QSymbol {
public QSymbolElementImpl(ASTNode node) {
super(node);
}

@Override
public String getName() {
return getText().substring(1);
}

@Override
public @Nullable String getQualifiedName() {
return getName();
}

@Override
public ItemPresentation getPresentation() {
return new VariablePresentation(this, KdbIcons.Node.Symbol);
}

@Override
public int getTextOffset() {
return super.getTextOffset() + 1;
}

@Override
public @Nullable PsiElement getNameIdentifier() {
return this;
}

@Override
public PsiElement setName(@NotNull String newName) throws IncorrectOperationException {
Optional.ofNullable(QPsiUtil.createSymbol(getProject(), newName.charAt(0) == '`' ? newName : "`" + newName))
.map(QSymbol::getFirstChild)
.map(PsiElement::getNode)
.ifPresent(newKeyNode -> {
final ASTNode keyNode = getNode().getFirstChildNode();
getNode().replaceChild(keyNode, newKeyNode);
});
return this;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.kdb.inside.brains.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.kdb.inside.brains.psi.*;
Expand Down Expand Up @@ -45,8 +46,9 @@ private String calculateQualifiedName() {
return name;
}

// It's namespace name itself - ignore
if (getParent() instanceof QContext) {
// It's namespace name itself or table column - ignore
final PsiElement parent = getParent();
if (parent instanceof QContext || parent instanceof QTableColumn) {
return name;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import icons.KdbIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.kdb.inside.brains.psi.QPsiUtil;
import org.kdb.inside.brains.psi.QVarDeclaration;
import org.kdb.inside.brains.psi.QVariable;

import javax.swing.*;
import java.util.Optional;

public abstract class QVariableDeclarationImpl extends QVariableBase implements QVarDeclaration {
Expand All @@ -38,26 +36,6 @@ public PsiElement setName(@NotNull String newName) {

@Override
public ItemPresentation getPresentation() {
return new ItemPresentation() {
@NotNull
@Override
public String getPresentableText() {
return getQualifiedName();
}

@NotNull
@Override
public String getLocationString() {
final PsiFile containingFile = getContainingFile();
return containingFile == null ? "" : containingFile.getName();
}

@NotNull
@Override
public Icon getIcon(boolean unused) {
// TODO: Not implemented yet. Icon should depends on the variable type and visibility
return KdbIcons.Node.Variable;
}
};
return new VariablePresentation(this, KdbIcons.Node.Variable);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.kdb.inside.brains.psi.impl;

import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiQualifiedNamedElement;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

class VariablePresentation implements ItemPresentation {
private final Icon icon;
private final PsiQualifiedNamedElement element;

public VariablePresentation(PsiQualifiedNamedElement element, Icon icon) {
this.element = element;
this.icon = icon;
}

@Override
public @Nullable Icon getIcon(boolean unused) {
return icon;
}

@Override
public @Nullable String getPresentableText() {
return element.getQualifiedName();
}

@Override
public @Nullable String getLocationString() {
final PsiFile containingFile = element.getContainingFile();
return containingFile == null ? "" : containingFile.getName();
}
}
Loading

0 comments on commit 4fe4ac2

Please sign in to comment.