-
Notifications
You must be signed in to change notification settings - Fork 305
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add visibility reference contributor (#5650)
Complete visibility refernce in build files with a custom logic to present pseudo visibility like __pkg__ and __subpackages__ as well as package groups, but not general targets.
- Loading branch information
1 parent
ea225b6
commit 79d55e7
Showing
14 changed files
with
269 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
base/src/com/google/idea/blaze/base/lang/buildfile/references/VisibilityReference.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package com.google.idea.blaze.base.lang.buildfile.references; | ||
|
||
import com.google.common.collect.ImmutableSet; | ||
import com.google.idea.blaze.base.lang.buildfile.completion.FilePathLookupElement; | ||
import com.google.idea.blaze.base.lang.buildfile.completion.LabelRuleLookupElement; | ||
import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral; | ||
import com.google.idea.blaze.base.model.primitives.Label; | ||
import com.intellij.codeInsight.lookup.LookupElement; | ||
import com.intellij.codeInsight.lookup.LookupElementBuilder; | ||
import com.intellij.icons.AllIcons; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class VisibilityReference extends LabelReference { | ||
|
||
private static final ImmutableSet<String> PSEUDO_VISIBILITIES = | ||
ImmutableSet.of("__pkg__", "__subpackages__"); | ||
|
||
public VisibilityReference(StringLiteral element, boolean soft) { | ||
super(element, soft); | ||
} | ||
|
||
@Override | ||
public Object[] getVariants() { | ||
Object[] variants = super.getVariants(); | ||
ArrayList<LookupElement> results = new ArrayList<>(); | ||
for (Object v : variants) { | ||
if (v instanceof FilePathLookupElement) { | ||
FilePathLookupElement le = ((FilePathLookupElement) v); | ||
if (le.getIsDirectory()) { | ||
results.add( | ||
LookupElementBuilder.create("\"" + le.getLabel() + "/") | ||
.withPresentableText(le.getLabel()) | ||
.withIcon(AllIcons.Nodes.Variable)); | ||
results.addAll(createPseudoVisibilitiesForPackage(le.getLabel())); | ||
} | ||
|
||
} else if (v instanceof LabelRuleLookupElement) { | ||
LabelRuleLookupElement le = ((LabelRuleLookupElement) v); | ||
if (le.getRuleType().equals("package_group")) { | ||
results.add(((LookupElement) le)); | ||
Label lbl = Label.createIfValid(le.getLabel()); | ||
if (lbl != null) { | ||
String pkg = "//" + lbl.blazePackage(); | ||
results.addAll(createPseudoVisibilitiesForPackage(pkg)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
ArrayList<String> globalVisibilities = new ArrayList<>(); | ||
globalVisibilities.add("//visibility:public"); | ||
globalVisibilities.add("//visibility:private"); | ||
|
||
for (String v : globalVisibilities) { | ||
results.add( | ||
LookupElementBuilder.create("\"" + v) | ||
.withIcon(AllIcons.Nodes.Variable) | ||
.withPresentableText(v)); | ||
results.add( | ||
LookupElementBuilder.create("'" + v) | ||
.withIcon(AllIcons.Nodes.Variable) | ||
.withPresentableText(v)); | ||
} | ||
|
||
return results.toArray(); | ||
} | ||
|
||
private List<LookupElement> createPseudoVisibilitiesForPackage(String pkg) { | ||
List<LookupElement> result = new ArrayList<>(PSEUDO_VISIBILITIES.size() * 2); | ||
for (String pv : PSEUDO_VISIBILITIES) { | ||
result.add( | ||
LookupElementBuilder.create("\"" + pkg + ":" + pv) | ||
.withPresentableText(pkg + ":" + pv) | ||
.withIcon(AllIcons.Nodes.Variable)); | ||
result.add( | ||
LookupElementBuilder.create("'" + pkg + ":" + pv) | ||
.withPresentableText(pkg + ":" + pv) | ||
.withIcon(AllIcons.Nodes.Variable)); | ||
} | ||
return result; | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
.../com/google/idea/blaze/base/lang/buildfile/references/VisibilityReferenceContributor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.google.idea.blaze.base.lang.buildfile.references; | ||
|
||
import com.intellij.psi.PsiReferenceContributor; | ||
import com.intellij.psi.PsiReferenceRegistrar; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
public class VisibilityReferenceContributor extends PsiReferenceContributor { | ||
@Override | ||
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { | ||
registrar.registerReferenceProvider( | ||
VisibilityReferenceProvider.PATTERN, new VisibilityReferenceProvider()); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
...src/com/google/idea/blaze/base/lang/buildfile/references/VisibilityReferenceProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.google.idea.blaze.base.lang.buildfile.references; | ||
|
||
import static com.intellij.patterns.PlatformPatterns.psiElement; | ||
|
||
import com.google.common.collect.ImmutableSet; | ||
import com.google.idea.blaze.base.lang.buildfile.language.BuildFileLanguage; | ||
import com.google.idea.blaze.base.lang.buildfile.psi.Argument; | ||
import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral; | ||
import com.intellij.patterns.ElementPattern; | ||
import com.intellij.patterns.PatternCondition; | ||
import com.intellij.patterns.PatternConditionPlus; | ||
import com.intellij.patterns.StandardPatterns; | ||
import com.intellij.psi.PsiElement; | ||
import com.intellij.psi.PsiReference; | ||
import com.intellij.psi.PsiReferenceProvider; | ||
import com.intellij.psi.impl.PsiElementBase; | ||
import com.intellij.util.PairProcessor; | ||
import com.intellij.util.ProcessingContext; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
public class VisibilityReferenceProvider extends PsiReferenceProvider | ||
implements AttributeSpecificStringLiteralReferenceProvider { | ||
|
||
private static final ImmutableSet<String> VISIBILITY_STRING_TYPES = ImmutableSet.of("visibility"); | ||
|
||
public static final ElementPattern<StringLiteral> PATTERN = | ||
psiElement(StringLiteral.class) | ||
.withLanguage(BuildFileLanguage.INSTANCE) | ||
.inside( | ||
psiElement(Argument.Keyword.class) | ||
.with(nameCondition(StandardPatterns.string().oneOf(VISIBILITY_STRING_TYPES)))); | ||
|
||
private static PatternCondition<PsiElementBase> nameCondition(final ElementPattern<?> pattern) { | ||
return new PatternConditionPlus<PsiElementBase, String>("_withPsiName", pattern) { | ||
@Override | ||
public boolean processValues( | ||
PsiElementBase t, | ||
ProcessingContext context, | ||
PairProcessor<? super String, ? super ProcessingContext> processor) { | ||
return processor.process(t.getName(), context); | ||
} | ||
}; | ||
} | ||
|
||
@Override | ||
public PsiReference[] getReferences(String attributeName, StringLiteral literal) { | ||
if (!VISIBILITY_STRING_TYPES.contains(attributeName)) { | ||
return PsiReference.EMPTY_ARRAY; | ||
} | ||
return new PsiReference[] {new VisibilityReference(literal, true)}; | ||
} | ||
|
||
@Override | ||
public PsiReference[] getReferencesByElement( | ||
@NotNull PsiElement psiElement, @NotNull ProcessingContext processingContext) { | ||
return new PsiReference[] {psiElement.getReference()}; | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
...ntests/com/google/idea/blaze/base/lang/buildfile/completion/VisibilityCompletionTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright 2023 The Bazel Authors. All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.google.idea.blaze.base.lang.buildfile.completion; | ||
|
||
import static com.google.common.truth.Truth.assertThat; | ||
|
||
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase; | ||
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile; | ||
import com.google.idea.blaze.base.model.primitives.WorkspacePath; | ||
import com.intellij.openapi.editor.Editor; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.JUnit4; | ||
|
||
@RunWith(JUnit4.class) | ||
public class VisibilityCompletionTest extends BuildFileIntegrationTestCase { | ||
|
||
@Test | ||
public void testVisibilityReferenceWithDoubleQuote() throws Throwable { | ||
BuildFile file = createBuildFile(new WorkspacePath("BUILD"), "sh_binary(visibility = [\"/\"])"); | ||
|
||
Editor editor = editorTest.openFileInEditor(file); | ||
editorTest.setCaretPosition(editor, 0, "sh_binary(visibility = [\"/".length()); | ||
|
||
assertThat(editorTest.getCompletionItemsAsStrings()) | ||
.asList() | ||
.containsExactly("\"//visibility:private", "\"//visibility:public"); | ||
} | ||
|
||
@Test | ||
public void testVisibilityReferenceWithSimpleQuote() throws Throwable { | ||
BuildFile file = createBuildFile(new WorkspacePath("BUILD"), "sh_binary(visibility = ['/'])"); | ||
|
||
Editor editor = editorTest.openFileInEditor(file); | ||
editorTest.setCaretPosition(editor, 0, "sh_binary(visibility = ['/".length()); | ||
|
||
assertThat(editorTest.getCompletionItemsAsStrings()) | ||
.asList() | ||
.containsExactly("'//visibility:private", "'//visibility:public"); | ||
} | ||
|
||
@Test | ||
public void testVisibilityReferenceWithOtherPackages() throws Throwable { | ||
createBuildFile(new WorkspacePath("pkg/foo/BUILD"), ""); | ||
BuildFile file = createBuildFile(new WorkspacePath("BUILD"), "sh_binary(visibility = ['/'])"); | ||
|
||
Editor editor = editorTest.openFileInEditor(file); | ||
editorTest.setCaretPosition(editor, 0, "sh_binary(visibility = ['/".length()); | ||
|
||
assertThat(editorTest.getCompletionItemsAsStrings()) | ||
.asList() | ||
.containsExactly( | ||
"'//visibility:private", | ||
"'//visibility:public", | ||
"'//pkg/foo:__pkg__", | ||
"'//pkg/foo:__subpackages__"); | ||
} | ||
|
||
@Test | ||
public void testVisibilityReferenceWithPackageGroup() throws Throwable { | ||
createBuildFile(new WorkspacePath("pkg/foo/BUILD"), "package_group(name = 'bob')"); | ||
BuildFile file = | ||
createBuildFile(new WorkspacePath("BUILD"), "sh_binary(visibility = ['//pkg/foo:'])"); | ||
|
||
Editor editor = editorTest.openFileInEditor(file); | ||
editorTest.setCaretPosition(editor, 0, "sh_binary(visibility = ['//pkg/foo:".length()); | ||
|
||
assertThat(editorTest.getCompletionItemsAsStrings()) | ||
.asList() | ||
.containsExactly( | ||
"'//pkg/foo:bob'", | ||
"'//pkg/foo:__pkg__", | ||
"'//pkg/foo:__subpackages__"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters