blob: 7eb16c0eee6768a1ac318e7e5fa6df8e23d2aba1 [file] [log] [blame]
/*
* Copyright 2016 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.references;
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.Argument;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.google.idea.blaze.base.lang.buildfile.search.FindUsages;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests that string literal references are correctly resolved. */
@RunWith(JUnit4.class)
public class LabelReferenceTest extends BuildFileIntegrationTestCase {
@Test
public void testExternalFileReference() {
BuildFile file =
createBuildFile(
new WorkspacePath("java/com/google/BUILD"),
"exports_files([\"test.txt\", \"//java/com/google:plugin.xml\"])");
PsiFile txtFile = workspace.createPsiFile(new WorkspacePath("java/com/google/test.txt"));
PsiFile xmlFile = workspace.createPsiFile(new WorkspacePath("java/com/google/plugin.xml"));
List<StringLiteral> strings =
PsiUtils.findAllChildrenOfClassRecursive(file, StringLiteral.class);
assertThat(strings).hasSize(2);
assertThat(strings.get(0).getReferencedElement()).isEqualTo(txtFile);
assertThat(strings.get(1).getReferencedElement()).isEqualTo(xmlFile);
}
@Test
public void testLocalRuleReference() {
BuildFile file =
createBuildFile(
new WorkspacePath("java/com/google/BUILD"),
"java_library(name = \"lib\")",
"java_library(name = \"foo\", deps = [\":lib\"])",
"java_library(name = \"bar\", deps = [\"//java/com/google:lib\"])");
FuncallExpression lib = file.findRule("lib");
FuncallExpression foo = file.findRule("foo");
FuncallExpression bar = file.findRule("bar");
assertThat(lib).isNotNull();
StringLiteral label =
PsiUtils.findFirstChildOfClassRecursive(
foo.getKeywordArgument("deps"), StringLiteral.class);
assertThat(label.getReferencedElement()).isEqualTo(lib);
label =
PsiUtils.findFirstChildOfClassRecursive(
bar.getKeywordArgument("deps"), StringLiteral.class);
assertThat(label.getReferencedElement()).isEqualTo(lib);
}
@Test
public void testTargetInAnotherPackageResolves() {
BuildFile targetFile =
createBuildFile(new WorkspacePath("java/com/google/foo/BUILD"), "rule(name = \"target\")");
BuildFile referencingFile =
createBuildFile(
new WorkspacePath("java/com/google/bar/BUILD"),
"rule(name = \"other\", dep = \"//java/com/google/foo:target\")");
FuncallExpression target = targetFile.findRule("target");
assertThat(target).isNotNull();
Argument.Keyword depArgument = referencingFile.findRule("other").getKeywordArgument("dep");
assertThat(depArgument.getValue().getReferencedElement()).isEqualTo(target);
}
@Test
public void testRuleNameDoesntCrossPackageBoundaries() {
BuildFile targetFile =
createBuildFile(
new WorkspacePath("java/com/google/pkg/subpkg/BUILD"), "rule(name = \"target\")");
BuildFile referencingFile =
createBuildFile(
new WorkspacePath("java/com/google/pkg/BUILD"),
"rule(name = \"other\", dep = \":subpkg/target\")");
Argument.Keyword depArgument = referencingFile.findRule("other").getKeywordArgument("dep");
LabelReference ref = (LabelReference) depArgument.getValue().getReference();
assertThat(ref.resolve()).isNull();
editorTest.replaceStringContents(ref.getElement(), "//java/com/google/pkg/subpkg:target");
assertThat(ref.resolve()).isNotNull();
assertThat(ref.resolve()).isEqualTo(targetFile.findRule("target"));
}
@Test
public void testLabelWithImplicitRuleName() {
BuildFile targetFile =
createBuildFile(new WorkspacePath("java/com/google/foo/BUILD"), "rule(name = \"foo\")");
BuildFile referencingFile =
createBuildFile(
new WorkspacePath("java/com/google/bar/BUILD"),
"rule(name = \"other\", dep = \"//java/com/google/foo\")");
FuncallExpression target = targetFile.findRule("foo");
assertThat(target).isNotNull();
Argument.Keyword depArgument = referencingFile.findRule("other").getKeywordArgument("dep");
assertThat(depArgument.getValue().getReferencedElement()).isEqualTo(target);
}
@Test
public void testAbsoluteLabelInSkylarkExtension() {
BuildFile targetFile =
createBuildFile(new WorkspacePath("java/com/google/foo/BUILD"), "rule(name = \"foo\")");
BuildFile referencingFile =
createBuildFile(
new WorkspacePath("java/com/google/foo/skylark.bzl"),
"LIST = ['//java/com/google/foo:foo']");
FuncallExpression target = targetFile.findRule("foo");
assertThat(target).isNotNull();
StringLiteral label =
PsiUtils.findFirstChildOfClassRecursive(referencingFile, StringLiteral.class);
assertThat(label.getReferencedElement()).isEqualTo(target);
}
@Test
public void testRulePreferredOverFile() {
BuildFile targetFile =
createBuildFile(new WorkspacePath("java/com/foo/BUILD"), "java_library(name = 'lib')");
workspace.createDirectory(new WorkspacePath("java/com/foo/lib"));
BuildFile referencingFile =
createBuildFile(
new WorkspacePath("java/com/google/bar/BUILD"),
"java_library(",
" name = 'bar',",
" src = glob(['**/*.java'])," + " deps = ['//java/com/foo:lib'],",
")");
FuncallExpression target = targetFile.findRule("lib");
assertThat(target).isNotNull();
PsiReference[] references = FindUsages.findAllReferences(target);
assertThat(references).hasLength(1);
PsiElement element = references[0].getElement();
FuncallExpression rule = PsiUtils.getParentOfType(element, FuncallExpression.class, true);
assertThat(rule.getName()).isEqualTo("bar");
assertThat(rule.getContainingFile()).isEqualTo(referencingFile);
}
}