RUBY-12492 Supported aliases in file structure

Also org.jetbrains.yaml.structureView package was refactored
This commit is contained in:
Alexey Merkulov
2018-05-24 18:13:10 +03:00
parent 840ccd5b7e
commit 2d8b758a66
14 changed files with 646 additions and 184 deletions
@@ -40,6 +40,9 @@ YamlScalarType.error.scalar.value=Scalar value expected
YamlIntegerType.error.integer.value=Integer value expected
YamlNumberType.error.numeric.value=Numeric value expected
YAMLStructureViewDocument.element.name=YAML document
YAMLStructureViewSequenceItem.element.name=Sequence Item
YAMLParser.invalid.header.symbols=Invalid block scalar header
YAMLParser.multiple.anchors=Multiple anchors are not permitted
YAMLParser.multiple.tags=Multiple tags are not permitted
@@ -47,6 +50,9 @@ YAMLParser.multiple.tags=Multiple tags are not permitted
YAMLAnchorRenameProcessor.lost.alias=Alias will refer to another anchor
YAMLAnchorRenameProcessor.reuse=Anchor already has the same name
YAMLAliasResolveNodeProvider.action.name=Show aliased sub-trees
YAMLAliasResolveNodeProvider.action.description=Resolve aliases and show referenced values in the structure
inspections.group.name=YAML
inspections.unresolved.alias.name=Unresolved alias
inspections.unresolved.alias.message=Can''t resolve alias {0}
@@ -0,0 +1,175 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.ide.util.treeView.AbstractTreeUi;
import com.intellij.ide.util.treeView.NodeDescriptorProvidingKey;
import com.intellij.ide.util.treeView.TreeAnchorizer;
import com.intellij.navigation.ItemPresentation;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Objects;
/**
* File structure popup work with unique values (see {@link StructureViewTreeElement#getValue()}).
* If it is needed to show the same PSI element several times then each occurrence of such psi should be wrapped to some unique object.
* This class perform this task.
* <p/>
* This class could be moved to some common platform package if it will be needed for somebody else.
* The implementation of this class is based on {@link PsiTreeElementBase} implementation (copy-pasted and modified).
*/
abstract class DuplicatedPsiTreeElementBase<T extends PsiElement & Navigatable> implements StructureViewTreeElement,
ItemPresentation,
NodeDescriptorProvidingKey {
@NotNull
private final StoredData<T> myValue;
/** @param details is used to distinguish different occurrences of the same PSI element */
protected DuplicatedPsiTreeElementBase(@NotNull T psiElement, @NotNull String details) {
myValue = new StoredData<>(psiElement, details);
}
/** @return stored psi element */
@NotNull
public final T getElement() {
return getValue().getElement();
}
/** @return additional information which is used to distinguish different occurrences of the same PSI element */
@NotNull
public final String getDetails() {
return getValue().getDetails();
}
@NotNull
public abstract Collection<StructureViewTreeElement> getChildrenBase();
@NotNull
@Override
public ItemPresentation getPresentation() {
return this;
}
@NotNull
@Override
public Object getKey() {
return String.valueOf(getElement());
}
@Contract(pure = true)
@NotNull
@Override
public final StoredData<T> getValue() {
return myValue;
}
public String toString() {
return getElement().toString();
}
@NotNull
@Override
public final StructureViewTreeElement[] getChildren() {
return AbstractTreeUi.calculateYieldingToWriteAction(this::doGetChildren);
}
@NotNull
private StructureViewTreeElement[] doGetChildren() {
return PsiTreeElementBase.mergeWithExtensions(getElement(), getChildrenBase());
}
@Override
public void navigate(boolean requestFocus) {
getElement().navigate(requestFocus);
}
@Override
public boolean canNavigate() {
return getElement().canNavigate();
}
@Override
public boolean canNavigateToSource() {
return canNavigate();
}
@Contract(value = "null -> false", pure = true)
public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final DuplicatedPsiTreeElementBase that = (DuplicatedPsiTreeElementBase)o;
return getValue().equals(that.getValue());
}
public int hashCode() {
return getValue().hashCode();
}
public boolean isValid() {
return true;
}
/** This class is a wrapper over PSI element with additional information */
private static class StoredData<T extends Navigatable> implements Navigatable {
@NotNull
private final Object myAnchor;
@NotNull
private final String myDetails;
public StoredData(@NotNull T element, @NotNull String details) {
myAnchor = TreeAnchorizer.getService().createAnchor(element);
myDetails = details;
}
@NotNull
public T getElement() {
@SuppressWarnings("unchecked")
T element = (T)TreeAnchorizer.getService().retrieveElement(myAnchor);
assert element != null;
return element;
}
@NotNull
public String getDetails() {
return myDetails;
}
@Override
public void navigate(boolean requestFocus) {
getElement().navigate(requestFocus);
}
@Override
public boolean canNavigate() {
return getElement().canNavigate();
}
@Override
public boolean canNavigateToSource() {
return getElement().canNavigateToSource();
}
@Contract(value = "null -> false", pure = true)
@Override
public boolean equals(@Nullable Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StoredData<?> data = (StoredData<?>)o;
return Objects.equals(getElement(), data.getElement()) &&
Objects.equals(getDetails(), data.getDetails());
}
@Override
public int hashCode() {
return Objects.hash(getElement(), getDetails());
}
}
}
@@ -0,0 +1,103 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.ActionShortcutProvider;
import com.intellij.ide.util.FileStructureNodeProvider;
import com.intellij.ide.util.treeView.smartTree.ActionPresentation;
import com.intellij.ide.util.treeView.smartTree.ActionPresentationData;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.YAMLBundle;
import org.jetbrains.yaml.psi.*;
import org.jetbrains.yaml.resolve.YAMLAliasReference;
import java.util.Collection;
import java.util.Collections;
public class YAMLAliasResolveNodeProvider implements FileStructureNodeProvider<StructureViewTreeElement>, ActionShortcutProvider {
@NonNls public static final String ID = "YAML_SHOW_RESOLVED_ALIAS_VALUES";
@NotNull
@Override
public String getCheckBoxText() {
return YAMLBundle.message("YAMLAliasResolveNodeProvider.action.name");
}
@NotNull
@Override
public Shortcut[] getShortcut() {
throw new IncorrectOperationException("see getActionIdForShortcut()");
}
@NotNull
@Override
public String getActionIdForShortcut() {
return "FileStructurePopup";
}
@NotNull
@Override
public Collection<StructureViewTreeElement> provideNodes(@NotNull TreeElement node) {
if (!(node instanceof DuplicatedPsiTreeElementBase)) {
return Collections.emptyList();
}
DuplicatedPsiTreeElementBase yamlNode = (DuplicatedPsiTreeElementBase)node;
PsiElement psiElem = yamlNode.getElement();
YAMLPsiElement yamlElem = psiElem instanceof YAMLPsiElement ? (YAMLPsiElement)psiElem : null;
YAMLValue value = getContainedValue(yamlElem);
if (!(value instanceof YAMLAlias)) {
return Collections.emptyList();
}
return YAMLStructureViewFactory.createChildrenViewTreeElements(resolveAlias((YAMLAlias)value), yamlNode.getDetails());
}
@NotNull
@Override
public ActionPresentation getPresentation() {
return new ActionPresentationData(YAMLBundle.message("YAMLAliasResolveNodeProvider.action.name"),
YAMLBundle.message("YAMLAliasResolveNodeProvider.action.description"),
YAMLStructureViewFactory.ALIAS_ICON);
}
@NotNull
@Override
public String getName() {
return ID;
}
@Nullable
private static YAMLValue resolveAlias(@NotNull YAMLAlias alias) {
YAMLAliasReference ref = alias.getReference();
YAMLAnchor anchor = ref == null ? null : ref.resolve();
return anchor != null ? anchor.getMarkedValue() : null;
}
@Nullable
@Contract("null -> null")
private static YAMLValue getContainedValue(@Nullable YAMLPsiElement element) {
if (element == null) {
return null;
}
Ref<YAMLValue> result = Ref.create();
element.accept(new YamlPsiElementVisitor() {
@Override
public void visitKeyValue(@NotNull YAMLKeyValue keyValue) {
result.set(keyValue.getValue());
}
@Override
public void visitSequenceItem(@NotNull YAMLSequenceItem sequenceItem) {
result.set(sequenceItem.getValue());
}
});
return result.get();
}
}
@@ -1,31 +0,0 @@
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.StructureViewModelBase;
import com.intellij.ide.structureView.TreeBasedStructureViewBuilder;
import com.intellij.ide.util.treeView.smartTree.Sorter;
import com.intellij.openapi.editor.Editor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.psi.YAMLDocument;
import org.jetbrains.yaml.psi.YAMLFile;
import org.jetbrains.yaml.psi.YAMLKeyValue;
/**
* @author oleg
*/
public class YAMLStructureViewBuilder extends TreeBasedStructureViewBuilder {
private final YAMLFile myPsiFile;
public YAMLStructureViewBuilder(@NotNull final YAMLFile psiFile) {
myPsiFile = psiFile;
}
@Override
@NotNull
public StructureViewModel createStructureViewModel(@Nullable Editor editor) {
return new StructureViewModelBase(myPsiFile, editor, new YAMLStructureViewElement(myPsiFile))
.withSorters(Sorter.ALPHA_SORTER)
.withSuitableClasses(YAMLFile.class, YAMLDocument.class, YAMLKeyValue.class);
}
}
@@ -0,0 +1,36 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.yaml.YAMLBundle;
import org.jetbrains.yaml.psi.YAMLDocument;
import javax.swing.*;
import java.util.Collection;
import java.util.Objects;
class YAMLStructureViewDocument extends PsiTreeElementBase<YAMLDocument> {
YAMLStructureViewDocument(@NotNull YAMLDocument psiElement) {
super(psiElement);
}
@NotNull
@Override
public Collection<StructureViewTreeElement> getChildrenBase() {
YAMLDocument document = Objects.requireNonNull(getElement());
return YAMLStructureViewFactory.createChildrenViewTreeElements(document.getTopLevelValue(), "<doc>");
}
@NotNull
public String getPresentableText() {
return YAMLBundle.message("YAMLStructureViewDocument.element.name");
}
@NotNull
public Icon getIcon(boolean open) {
return PlatformIcons.XML_TAG_ICON;
}
}
@@ -1,150 +0,0 @@
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.psi.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author oleg
*/
public class YAMLStructureViewElement implements StructureViewTreeElement {
private final YAMLPsiElement myElement;
public YAMLStructureViewElement(final YAMLPsiElement element) {
myElement = element;
}
@NotNull
public StructureViewTreeElement[] getChildren() {
final Collection<? extends YAMLPsiElement> children;
if (myElement instanceof YAMLFile) {
children = ((YAMLFile)myElement).getDocuments();
}
else if (myElement instanceof YAMLDocument) {
children = getChildrenForValue(((YAMLDocument)myElement).getTopLevelValue());
}
else if (myElement instanceof YAMLSequenceItem) {
children = getChildrenForValue(((YAMLSequenceItem)myElement).getValue());
}
else if (myElement instanceof YAMLKeyValue) {
children = getChildrenForValue(((YAMLKeyValue)myElement).getValue());
}
else {
children = Collections.emptyList();
}
final List<StructureViewTreeElement> structureElements = new ArrayList<>();
for (YAMLPsiElement child : children) {
structureElements.add(new YAMLStructureViewElement(child));
}
return structureElements.toArray(StructureViewTreeElement.EMPTY_ARRAY);
}
@NotNull
private static Collection<? extends YAMLPsiElement> getChildrenForValue(@Nullable YAMLPsiElement element) {
if (element instanceof YAMLMapping) {
return ((YAMLMapping)element).getKeyValues();
}
if (element instanceof YAMLSequence) {
return ((YAMLSequence)element).getItems();
}
return Collections.emptyList();
}
@NotNull
public ItemPresentation getPresentation() {
if (myElement instanceof YAMLKeyValue){
final YAMLKeyValue kv = (YAMLKeyValue)myElement;
return new ItemPresentation() {
public String getPresentableText() {
return kv.getKeyText();
}
public String getLocationString() {
if (kv.getValue() instanceof YAMLScalar) {
return kv.getValueText();
}
else {
return null;
}
}
public Icon getIcon(boolean open) {
final YAMLValue value = kv.getValue();
return value instanceof YAMLScalar ? kv.getIcon(0) : PlatformIcons.XML_TAG_ICON;
}
};
}
if (myElement instanceof YAMLDocument){
return new ItemPresentation() {
public String getPresentableText() {
return "YAML document";
}
public String getLocationString() {
return null;
}
public Icon getIcon(boolean open) {
return PlatformIcons.XML_TAG_ICON;
}
};
}
if (myElement instanceof YAMLSequenceItem) {
final YAMLSequenceItem item = ((YAMLSequenceItem)myElement);
return new ItemPresentation() {
@Nullable
@Override
public String getPresentableText() {
if (item.getValue() instanceof YAMLScalar) {
return ((YAMLScalar)item.getValue()).getTextValue();
}
else {
return "Sequence Item";
}
}
@Nullable
@Override
public String getLocationString() {
return null;
}
@Nullable
@Override
public Icon getIcon(boolean unused) {
return item.getValue() instanceof YAMLScalar ? PlatformIcons.PROPERTY_ICON : PlatformIcons.XML_TAG_ICON;
}
};
}
return myElement.getPresentation();
}
public YAMLPsiElement getValue() {
return myElement;
}
public void navigate(boolean requestFocus) {
myElement.navigate(requestFocus);
}
public boolean canNavigate() {
return myElement.canNavigate();
}
public boolean canNavigateToSource() {
return myElement.canNavigateToSource();
}
}
@@ -1,16 +1,34 @@
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.icons.AllIcons;
import com.intellij.ide.structureView.*;
import com.intellij.ide.util.treeView.smartTree.NodeProvider;
import com.intellij.ide.util.treeView.smartTree.Sorter;
import com.intellij.lang.PsiStructureViewFactory;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiFile;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.yaml.psi.YAMLFile;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.psi.*;
import javax.swing.*;
import java.util.Collection;
import java.util.Collections;
/**
* @author oleg
*/
public class YAMLStructureViewFactory implements PsiStructureViewFactory {
static final Icon ALIAS_ICON = AllIcons.Nodes.ExpandNode;
@Nullable
public StructureViewBuilder getStructureViewBuilder(@NotNull final PsiFile psiFile) {
if (!(psiFile instanceof YAMLFile)) {
return null;
}
for (YAMLCustomStructureViewFactory extension : YAMLCustomStructureViewFactory.EP_NAME.getExtensions()) {
final StructureViewBuilder builder = extension.getStructureViewBuilder((YAMLFile)psiFile);
if (builder != null) {
@@ -18,6 +36,44 @@ public class YAMLStructureViewFactory implements PsiStructureViewFactory {
}
}
return new YAMLStructureViewBuilder((YAMLFile) psiFile);
return new TreeBasedStructureViewBuilder() {
@Override
@NotNull
public StructureViewModel createStructureViewModel(@Nullable Editor editor) {
return new StructureViewModelBase(psiFile, editor, new YAMLStructureViewFile((YAMLFile)psiFile)){
@NotNull
@Override
public Collection<NodeProvider> getNodeProviders() {
return Collections.singleton(new YAMLAliasResolveNodeProvider());
}
}
.withSorters(Sorter.ALPHA_SORTER)
.withSuitableClasses(YAMLFile.class, YAMLDocument.class, YAMLKeyValue.class);
}
};
}
@NotNull
static String getAliasPresentableText(@NotNull YAMLAlias alias) {
return "*" + alias.getAliasName();
}
@NotNull
static Collection<StructureViewTreeElement> createChildrenViewTreeElements(@Nullable YAMLPsiElement element, String path) {
if (element == null) {
return Collections.emptyList();
}
Ref<Collection<StructureViewTreeElement>> result = Ref.create(Collections.emptyList());
element.accept(new YamlPsiElementVisitor() {
@Override
public void visitSequence(@NotNull YAMLSequence sequence) {
result.set(ContainerUtil.map(sequence.getItems(), i -> new YAMLStructureViewSequenceItem(i, path)));
}
@Override
public void visitMapping(@NotNull YAMLMapping mapping) {
result.set(ContainerUtil.map(mapping.getKeyValues(), kv -> new YAMLStructureViewKeyValue(kv, path)));
}
});
return result.get();
}
}
@@ -0,0 +1,49 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import com.intellij.navigation.ItemPresentation;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.psi.YAMLFile;
import javax.swing.*;
import java.util.Collection;
import java.util.Objects;
class YAMLStructureViewFile extends PsiTreeElementBase<YAMLFile> {
YAMLStructureViewFile(@NotNull YAMLFile psiElement) {
super(psiElement);
}
@NotNull
@Override
public Collection<StructureViewTreeElement> getChildrenBase() {
YAMLFile file = Objects.requireNonNull(getElement());
return ContainerUtil.map(file.getDocuments(), YAMLStructureViewDocument::new);
}
@Nullable
@Override
public String getPresentableText() {
return getFilePresentation().getPresentableText();
}
@Nullable
public String getLocationString() {
return getFilePresentation().getLocationString();
}
@Nullable
public Icon getIcon(boolean unused) {
return getFilePresentation().getIcon(unused);
}
@NotNull
private ItemPresentation getFilePresentation() {
YAMLFile file = Objects.requireNonNull(getElement());
return Objects.requireNonNull(file.getPresentation());
}
}
@@ -0,0 +1,71 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.psi.YAMLAlias;
import org.jetbrains.yaml.psi.YAMLKeyValue;
import org.jetbrains.yaml.psi.YAMLScalar;
import org.jetbrains.yaml.psi.YAMLValue;
import javax.swing.*;
import java.util.Collection;
import java.util.Objects;
import static org.jetbrains.yaml.structureView.YAMLStructureViewFactory.ALIAS_ICON;
class YAMLStructureViewKeyValue extends DuplicatedPsiTreeElementBase<YAMLKeyValue> {
YAMLStructureViewKeyValue(@NotNull YAMLKeyValue kv, String path) {
super(kv, path + '.' + kv.getKeyText());
}
@NotNull
@Override
public Collection<StructureViewTreeElement> getChildrenBase() {
return YAMLStructureViewFactory.createChildrenViewTreeElements(getVal(), getDetails());
}
@NotNull
public String getPresentableText() {
return getKeyValue().getKeyText();
}
@Nullable
public String getLocationString() {
if (getVal() instanceof YAMLScalar) {
return getKeyValue().getValueText();
}
else if (getVal() instanceof YAMLAlias) {
return YAMLStructureViewFactory.getAliasPresentableText((YAMLAlias)getVal());
}
else {
return null;
}
}
@Nullable
public Icon getIcon(boolean open) {
if (getVal() instanceof YAMLScalar) {
return getKeyValue().getIcon(0);
}
else if (getVal() instanceof YAMLAlias) {
return ALIAS_ICON;
}
else {
return PlatformIcons.XML_TAG_ICON;
}
}
@NotNull
private YAMLKeyValue getKeyValue() {
return Objects.requireNonNull(getElement());
}
// Base class already has getValue() method with different semantic
@Nullable
private YAMLValue getVal() {
return getKeyValue().getValue();
}
}
@@ -0,0 +1,77 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.lang.ASTNode;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.YAMLBundle;
import org.jetbrains.yaml.psi.YAMLAlias;
import org.jetbrains.yaml.psi.YAMLScalar;
import org.jetbrains.yaml.psi.YAMLSequenceItem;
import org.jetbrains.yaml.psi.YAMLValue;
import javax.swing.*;
import java.util.Collection;
import static org.jetbrains.yaml.structureView.YAMLStructureViewFactory.ALIAS_ICON;
class YAMLStructureViewSequenceItem extends DuplicatedPsiTreeElementBase<YAMLSequenceItem> {
YAMLStructureViewSequenceItem(@NotNull YAMLSequenceItem item, String path) {
super(item, path + '-' + getItemNumber(item));
}
@NotNull
@Override
public Collection<StructureViewTreeElement> getChildrenBase() {
return YAMLStructureViewFactory.createChildrenViewTreeElements(getItemValue(), getDetails());
}
@NotNull
@Override
public String getPresentableText() {
if (getItemValue() instanceof YAMLScalar) {
return ((YAMLScalar)getItemValue()).getTextValue();
}
else if (getItemValue() instanceof YAMLAlias) {
return YAMLStructureViewFactory.getAliasPresentableText((YAMLAlias)getItemValue());
}
else {
return YAMLBundle.message("YAMLStructureViewSequenceItem.element.name");
}
}
@Nullable
@Override
public String getLocationString() {
return null;
}
@NotNull
@Override
public Icon getIcon(boolean unused) {
if (getItemValue() instanceof YAMLScalar) {
return PlatformIcons.PROPERTY_ICON;
}
else if (getItemValue() instanceof YAMLAlias) {
return ALIAS_ICON;
}
else {
return PlatformIcons.XML_TAG_ICON;
}
}
@Nullable
private YAMLValue getItemValue() {
return getElement().getValue();
}
private static int getItemNumber(@NotNull YAMLSequenceItem item) {
int num = 0;
for (ASTNode node = item.getNode().getTreePrev(); node != null; node = node.getTreePrev()) {
num++;
}
return num;
}
}
@@ -0,0 +1,38 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.yaml.structure;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.yaml.structureView.YAMLAliasResolveNodeProvider;
public class YAMLStructureTest extends LightPlatformCodeInsightFixtureTestCase {
@Override
protected String getTestDataPath() {
return PathManagerEx.getCommunityHomePath() + "/plugins/yaml/testSrc/org/jetbrains/yaml/structure/data/";
}
public void testAnchorsAndAliases() {
doTest();
}
private void doTest() {
String testName = getTestName(true);
myFixture.configureByFile(testName + ".yml");
doStructureTest(testName, false);
doStructureTest(testName, true);
}
private void doStructureTest(String testName, boolean resolveAliases) {
myFixture.testStructureView(svc -> {
svc.setActionActive(YAMLAliasResolveNodeProvider.ID, resolveAliases);
TreeUtil.expandAll(svc.getTree());
PlatformTestUtil.waitForPromise(svc.select(svc.getTreeModel().getCurrentEditorElement(), false));
String suffix = resolveAliases ? "resolved" : "unresolved";
assertSameLinesWithFile(getTestDataPath() + testName + "." + suffix + ".txt",
PlatformTestUtil.print(svc.getTree(), false));
});
}
}
@@ -0,0 +1,14 @@
-anchorsAndAliases.yml
-YAML document
-First occurrence
-list
item1
item2
-Second occurrence
-list
item1
item2
-Override anchor
key
-Reuse anchor
key
@@ -0,0 +1,10 @@
-anchorsAndAliases.yml
-YAML document
-First occurrence
-list
item1
item2
Second occurrence
-Override anchor
key
Reuse anchor
@@ -0,0 +1,8 @@
First occurrence: &xxx
list:
- item1
- item2
Second occurrence: *xxx
Override anchor: &xxx
key: val
Reuse anchor: *xxx