Import of bazel plugin using copybara
PiperOrigin-RevId: 148474984
diff --git a/WORKSPACE b/WORKSPACE
index bad62f5..bffcb5e 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -50,6 +50,14 @@
url = "https://dl.google.com/dl/android/studio/ide-zips/2.3.0.4/android-studio-ide-162.3616766-linux.zip",
)
+# The plugin api for Android Studio 2.3 Beta 4. This is required to build ASwB,
+# and run integration tests.
+new_http_archive(
+ name = "android_studio_2_3_0_6",
+ build_file = "intellij_platform_sdk/BUILD.android_studio",
+ url = "https://dl.google.com/dl/android/studio/ide-zips/2.3.0.6/android-studio-ide-162.3715353-linux.zip",
+)
+
# The plugin api for Android Studio 2.2 stable. This is required to build ASwB,
# and run integration tests.
new_http_archive(
diff --git a/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidTestCleanupHelper.java b/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestCleanupHelper.java
similarity index 97%
rename from aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidTestCleanupHelper.java
rename to aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestCleanupHelper.java
index 6847c67..d1b4a07 100644
--- a/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidTestCleanupHelper.java
+++ b/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestCleanupHelper.java
@@ -32,7 +32,7 @@
* TODO: Remove once we build for a version where post-initialization insight and style settings are
* used in the settings check.
*/
-public final class AndroidTestCleanupHelper {
+public final class AndroidIntegrationTestCleanupHelper {
public static void cleanUp(Project project) {
resetCodeInsightSettings();
diff --git a/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidTestSetupRule.java b/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestSetupRule.java
similarity index 91%
rename from aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidTestSetupRule.java
rename to aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestSetupRule.java
index 07fc1ac..293643f 100644
--- a/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidTestSetupRule.java
+++ b/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestSetupRule.java
@@ -23,7 +23,7 @@
* Runs before Android Studio integration tests, to ensure the AndroidStudio platform prefix is
* honored.
*/
-public class AndroidTestSetupRule extends ExternalResource {
+public class AndroidIntegrationTestSetupRule extends ExternalResource {
@Override
protected void before() throws Throwable {
@@ -33,6 +33,7 @@
// a matching descriptor for one of them. Notably, "AndroidStudio" is not a candidate.
// The first parameter doesn't matter in our case, so we pass a nonexistent class name.
PlatformTestCase.initPlatformPrefix("", System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY));
+ System.setProperty("android.studio.sdk.manager.disabled", "true");
// TODO: Remove the above once we build for a version where "AndroidStudio" is a candidate.
}
}
diff --git a/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java b/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java
deleted file mode 100644
index 106860a..0000000
--- a/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.android;
-
-import com.google.idea.blaze.base.BlazeIntegrationTestCase;
-import org.junit.After;
-import org.junit.Rule;
-
-/** Base test class for Blaze Android integration tests. */
-public abstract class BlazeAndroidIntegrationTestCase extends BlazeIntegrationTestCase {
-
- @Rule public final AndroidTestSetupRule androidSetupRule = new AndroidTestSetupRule();
-
- @After
- public final void doTeardown() {
- AndroidTestCleanupHelper.cleanUp(getProject());
- }
-}
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java
index fbd398d..ce41514 100755
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java
+++ b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java
@@ -165,7 +165,7 @@
}
private void mockBlazeImportSettings(Container projectServices) {
- BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager(project);
+ BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager();
importSettingsManager.setImportSettings(
new BlazeImportSettings("", "", "", "", "", Blaze.BuildSystem.Blaze));
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
index efd77ea..a33eb31 100644
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
+++ b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
@@ -27,7 +27,6 @@
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
-import com.google.idea.blaze.base.settings.BlazeImportSettingsManagerLegacy;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.common.experiments.ExperimentService;
import com.intellij.openapi.extensions.ExtensionPoint;
@@ -59,12 +58,10 @@
projectDataManager = new MockBlazeProjectDataManager();
projectServices.register(BlazeProjectDataManager.class, projectDataManager);
- BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager(project);
+ BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager();
importSettingsManager.setImportSettings(
new BlazeImportSettings(null, null, null, null, null, BuildSystem.Blaze));
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
- projectServices.register(
- BlazeImportSettingsManagerLegacy.class, new BlazeImportSettingsManagerLegacy(project));
ExtensionPoint<FeatureEnableService> extensionPoint =
registerExtensionPoint(
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java
index ffe8267..ee48a99 100644
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java
+++ b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java
@@ -44,7 +44,6 @@
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
-import com.google.idea.blaze.base.settings.BlazeImportSettingsManagerLegacy;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.base.targetmaps.SourceToTargetMap;
@@ -103,12 +102,10 @@
projectServices.register(
AndroidResourceModuleRegistry.class, new AndroidResourceModuleRegistry());
- BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager(project);
+ BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager();
BlazeImportSettings settings = new BlazeImportSettings("", "", "", "", "", BuildSystem.Blaze);
importSettingsManager.setImportSettings(settings);
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
- projectServices.register(
- BlazeImportSettingsManagerLegacy.class, new BlazeImportSettingsManagerLegacy(project));
createPsiClassesAndSourceToTargetMap(projectServices);
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java
index 86c20cf..e5a828d 100644
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java
+++ b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java
@@ -164,7 +164,7 @@
}
private void mockBlazeImportSettings(Container projectServices) {
- BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager(project);
+ BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager();
importSettingsManager.setImportSettings(
new BlazeImportSettings("", "", "", "", "", Blaze.BuildSystem.Blaze));
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
@@ -251,6 +251,11 @@
}
@Override
+ public String getBinaryPath() {
+ return "/usr/bin/blaze";
+ }
+
+ @Override
public WorkspaceRootProvider getWorkspaceRootProvider() {
return null;
}
@@ -278,8 +283,8 @@
}
@Override
- public FileNameMatcher buildFileMatcher() {
- return null;
+ public ImmutableList<FileNameMatcher> buildFileMatchers() {
+ return ImmutableList.of();
}
@Override
diff --git a/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java b/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestCleanupHelper.java
similarity index 64%
copy from aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java
copy to aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestCleanupHelper.java
index 74459a0..5f425ca 100644
--- a/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java
+++ b/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestCleanupHelper.java
@@ -16,7 +16,15 @@
package com.google.idea.blaze.android;
-import com.google.idea.blaze.base.BlazeIntegrationTestCase;
+import com.intellij.openapi.project.Project;
-/** Compatibility test class for Blaze Android integration tests. */
-public abstract class BlazeAndroidIntegrationTestCase extends BlazeIntegrationTestCase {}
+/**
+ * Helper class for cleaning up after Android Studio initialization.
+ *
+ * <p>This class exists only for 2.2 compatibility and can be removed once 2.2 support is removed.
+ */
+public final class AndroidIntegrationTestCleanupHelper {
+
+ @SuppressWarnings("unused")
+ public static void cleanUp(Project project) {}
+}
diff --git a/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java b/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestSetupRule.java
similarity index 68%
rename from aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java
rename to aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestSetupRule.java
index 74459a0..088e953 100644
--- a/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java
+++ b/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/AndroidIntegrationTestSetupRule.java
@@ -13,10 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.google.idea.blaze.android;
-import com.google.idea.blaze.base.BlazeIntegrationTestCase;
+import org.junit.rules.ExternalResource;
-/** Compatibility test class for Blaze Android integration tests. */
-public abstract class BlazeAndroidIntegrationTestCase extends BlazeIntegrationTestCase {}
+/** Runs before Android Studio integration tests. */
+public class AndroidIntegrationTestSetupRule extends ExternalResource {
+
+ @Override
+ protected void before() throws Throwable {
+ System.setProperty("android.studio.sdk.manager.disabled", "true");
+ }
+}
diff --git a/aswb/BUILD b/aswb/BUILD
index 16fc99b..7fe4a00 100644
--- a/aswb/BUILD
+++ b/aswb/BUILD
@@ -25,6 +25,7 @@
"android-studio-145.1617.8": [],
"android-studio-2.3.0.3": ["2.3/src/META-INF/aswb_beta.xml"],
"android-studio-2.3.0.4": ["2.3/src/META-INF/aswb_beta.xml"],
+ "android-studio-2.3.0.6": ["2.3/src/META-INF/aswb_beta.xml"],
}),
visibility = [
"//visibility:public",
@@ -56,6 +57,7 @@
"android-studio-145.1617.8": glob(["2.2/src/**/*.java"]),
"android-studio-2.3.0.3": glob(["2.3/src/**/*.java"]),
"android-studio-2.3.0.4": glob(["2.3/src/**/*.java"]),
+ "android-studio-2.3.0.6": glob(["2.3/src/**/*.java"]),
}),
resources = glob(["resources/**/*"]),
visibility = [
@@ -67,7 +69,7 @@
"//cpp",
"//intellij_platform_sdk:plugin_api",
"//java",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
],
)
@@ -80,6 +82,7 @@
"android-studio-145.1617.8": glob(["2.2/tests/utils/integration/**/*.java"]),
"android-studio-2.3.0.3": glob(["2.3/tests/utils/integration/**/*.java"]),
"android-studio-2.3.0.4": glob(["2.3/tests/utils/integration/**/*.java"]),
+ "android-studio-2.3.0.6": glob(["2.3/tests/utils/integration/**/*.java"]),
}),
deps = [
"//base",
@@ -104,6 +107,7 @@
"android-studio-145.1617.8": [],
"android-studio-2.3.0.3": glob(["2.3/tests/unittests/**/*.java"]),
"android-studio-2.3.0.4": glob(["2.3/tests/unittests/**/*.java"]),
+ "android-studio-2.3.0.6": glob(["2.3/tests/unittests/**/*.java"]),
}),
test_package_root = "com.google.idea.blaze.android",
deps = [
@@ -114,7 +118,7 @@
"//common/experiments:unit_test_utils",
"//intellij_platform_sdk:plugin_api_for_tests",
"//java",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
"@junit//jar",
],
@@ -127,6 +131,7 @@
"android-studio-145.1617.8": [],
"android-studio-2.3.0.3": glob(["2.3/tests/integrationtests/**/*.java"]),
"android-studio-2.3.0.4": glob(["2.3/tests/integrationtests/**/*.java"]),
+ "android-studio-2.3.0.6": glob(["2.3/tests/integrationtests/**/*.java"]),
}),
platform_prefix = "AndroidStudio",
required_plugins = "com.google.idea.bazel.aswb",
@@ -144,7 +149,7 @@
"//common/experiments:unit_test_utils",
"//intellij_platform_sdk:plugin_api_for_tests",
"//java",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
"@junit//jar",
],
diff --git a/aswb/src/META-INF/aswb.xml b/aswb/src/META-INF/aswb.xml
index d59d935..b4b61ab 100644
--- a/aswb/src/META-INF/aswb.xml
+++ b/aswb/src/META-INF/aswb.xml
@@ -40,6 +40,9 @@
<projectService serviceImplementation="com.google.idea.blaze.android.manifest.ManifestParser"/>
<projectService serviceImplementation="com.google.idea.blaze.android.sync.model.AndroidResourceModuleRegistry"/>
<applicationService serviceImplementation="com.google.idea.blaze.android.settings.BlazeAndroidUserSettings"/>
+ <applicationService serviceInterface="com.google.idea.blaze.android.sdk.BlazeSdkProvider"
+ serviceImplementation="com.google.idea.blaze.android.sdk.BlazeSdkProviderImpl"
+ testServiceImplementation="com.google.idea.blaze.android.sdk.MockBlazeSdkProvider"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.android.actions">
diff --git a/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java b/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java
index f6b50ae..75e1a12 100644
--- a/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java
+++ b/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java
@@ -25,11 +25,10 @@
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.BlazeSyncParams.SyncMode;
import com.google.idea.blaze.base.sync.SyncListener;
-import com.google.idea.blaze.cpp.BlazeCWorkspace;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.jetbrains.cidr.lang.workspace.OCWorkspace;
-import org.jetbrains.annotations.NotNull;
+import com.jetbrains.cidr.lang.workspace.OCWorkspaceManager;
final class BlazeNdkSupportEnabler extends SyncListener.Adapter {
@@ -57,7 +56,7 @@
* @param enabled if true, turn on C support in the IDE. If false, turn off C support in the IDE.
*/
private static void enableCSupportInIde(Project project, boolean enabled) {
- BlazeCWorkspace workspace = BlazeCWorkspace.getInstance(project);
+ OCWorkspace workspace = OCWorkspaceManager.getWorkspace(project);
Boolean isCurrentlyEnabled = !LANGUAGE_SUPPORT_DISABLED.get(project, false);
if (isCurrentlyEnabled != enabled) {
NdkHelper.disableCppLanguageSupport(project, !enabled);
@@ -65,7 +64,7 @@
}
}
- private static void rebuildSymbols(@NotNull Project project, @NotNull OCWorkspace workspace) {
+ private static void rebuildSymbols(Project project, OCWorkspace workspace) {
ApplicationManager.getApplication()
.runReadAction(
() -> {
diff --git a/aswb/src/com/google/idea/blaze/android/projectview/AndroidSdkPlatformSection.java b/aswb/src/com/google/idea/blaze/android/projectview/AndroidSdkPlatformSection.java
index fe75735..a9cbded 100644
--- a/aswb/src/com/google/idea/blaze/android/projectview/AndroidSdkPlatformSection.java
+++ b/aswb/src/com/google/idea/blaze/android/projectview/AndroidSdkPlatformSection.java
@@ -18,7 +18,7 @@
import static java.util.stream.Collectors.toList;
import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidSdkUtils;
+import com.google.idea.blaze.android.sdk.BlazeSdkProvider;
import com.google.idea.blaze.android.sync.sdk.AndroidSdkFromProjectView;
import com.google.idea.blaze.base.projectview.ProjectView;
import com.google.idea.blaze.base.projectview.parser.ParseContext;
@@ -66,7 +66,7 @@
if (!projectView.getSectionsOfType(KEY).isEmpty()) {
return projectView;
}
- List<Sdk> sdks = AndroidSdkUtils.getAllAndroidSdks();
+ List<Sdk> sdks = BlazeSdkProvider.getInstance().getAllAndroidSdks();
ProjectView.Builder builder =
ProjectView.builder(projectView).add(TextBlockSection.of(TextBlock.newLine()));
@@ -81,7 +81,7 @@
} else if (sdks.size() == 1) {
builder.add(
ScalarSection.builder(KEY)
- .set(AndroidSdkFromProjectView.getSdkTargetHash(sdks.get(0))));
+ .set(BlazeSdkProvider.getInstance().getSdkTargetHash(sdks.get(0))));
} else {
builder.add(
TextBlockSection.of(
diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeApkBuildStepMobileInstall.java b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeApkBuildStepMobileInstall.java
index 1256ff4..2082b77 100644
--- a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeApkBuildStepMobileInstall.java
+++ b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeApkBuildStepMobileInstall.java
@@ -23,11 +23,11 @@
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidSdkUtils;
import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo;
import com.google.idea.blaze.android.run.deployinfo.BlazeApkDeployInfoProtoHelper;
import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector;
import com.google.idea.blaze.android.run.runner.BlazeApkBuildStep;
+import com.google.idea.blaze.android.sdk.BlazeSdkProvider;
import com.google.idea.blaze.android.sync.model.AndroidSdkPlatform;
import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
@@ -99,7 +99,8 @@
}
BlazeCommand.Builder command =
BlazeCommand.builder(
- Blaze.getBuildSystem(project), BlazeCommandName.MOBILE_INSTALL);
+ Blaze.getBuildSystemProvider(project).getBinaryPath(),
+ BlazeCommandName.MOBILE_INSTALL);
command.addBlazeFlags(BlazeFlags.adbSerialFlags(device.getSerialNumber()));
if (USE_SDK_ADB.getValue()) {
@@ -186,7 +187,7 @@
if (androidSdkPlatform == null) {
return null;
}
- Sdk sdk = AndroidSdkUtils.findSuitableAndroidSdk(androidSdkPlatform.androidSdk);
+ Sdk sdk = BlazeSdkProvider.getInstance().findSdk(androidSdkPlatform.androidSdk);
if (sdk == null) {
return null;
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java
index 241fd76..ffe8c6e 100644
--- a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java
+++ b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java
@@ -91,7 +91,7 @@
BlazeInfo.getInstance()
.runBlazeInfo(
context,
- Blaze.getBuildSystem(project),
+ Blaze.getBuildSystemProvider(project).getBinaryPath(),
workspaceRoot,
buildFlags,
BlazeInfo.EXECUTION_ROOT_KEY);
diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeApkBuildStepNormalBuild.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeApkBuildStepNormalBuild.java
index 835aa1d..1029f85 100644
--- a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeApkBuildStepNormalBuild.java
+++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeApkBuildStepNormalBuild.java
@@ -63,7 +63,8 @@
@Override
protected void execute(@NotNull BlazeContext context) {
BlazeCommand.Builder command =
- BlazeCommand.builder(Blaze.getBuildSystem(project), BlazeCommandName.BUILD);
+ BlazeCommand.builder(
+ Blaze.getBuildSystemProvider(project).getBinaryPath(), BlazeCommandName.BUILD);
WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
command
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestClassRunConfigurationProducer.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestClassRunConfigurationProducer.java
index a9b9515..bbafcc0 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestClassRunConfigurationProducer.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestClassRunConfigurationProducer.java
@@ -75,7 +75,7 @@
}
sourceElement.set(testClass);
- TargetIdeInfo target = RunUtil.targetForTestClass(context.getProject(), testClass, null);
+ TargetIdeInfo target = RunUtil.targetForTestClass(testClass, null);
if (target == null) {
return false;
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java
index 7283e53..5bd9892 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestLaunchTask.java
@@ -132,7 +132,8 @@
BlazeCommand.Builder commandBuilder =
BlazeCommand.builder(
- Blaze.getBuildSystem(project), BlazeCommandName.TEST)
+ Blaze.getBuildSystemProvider(project).getBinaryPath(),
+ BlazeCommandName.TEST)
.addTargets(target);
// Build flags must match BlazeBeforeRunTask.
commandBuilder.addBlazeFlags(buildFlags);
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestMethodRunConfigurationProducer.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestMethodRunConfigurationProducer.java
index a0d4878..d3cbc78 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestMethodRunConfigurationProducer.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestMethodRunConfigurationProducer.java
@@ -74,7 +74,7 @@
return false;
}
- TargetIdeInfo target = RunUtil.targetForTestClass(context.getProject(), containingClass, null);
+ TargetIdeInfo target = RunUtil.targetForTestClass(containingClass, null);
if (target == null) {
return false;
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java
index 7f5fb95..fd99489 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunContext.java
@@ -45,7 +45,6 @@
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler;
-import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.executors.DefaultDebugExecutor;
@@ -61,9 +60,6 @@
/** Run context for android_test. */
class BlazeAndroidTestRunContext implements BlazeAndroidRunContext {
- private static final BoolExperiment smRunnerUiEnabled =
- new BoolExperiment("use.smrunner.ui.android", true);
-
private final Project project;
private final AndroidFacet facet;
private final BlazeCommandRunConfiguration runConfiguration;
@@ -97,7 +93,7 @@
this.apkProvider = new BlazeApkProvider(project, buildStep.getDeployInfo());
BlazeTestEventsHandler testEventsHandler = null;
- if (smRunnerUiEnabled.getValue() && !isDebugging(env.getExecutor())) {
+ if (!isDebugging(env.getExecutor())) {
testEventsHandler =
BlazeTestEventsHandler.getHandlerForTarget(project, runConfiguration.getTarget());
assert (testEventsHandler != null);
diff --git a/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProvider.java b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProvider.java
new file mode 100644
index 0000000..2222bd4
--- /dev/null
+++ b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017 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.android.sdk;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/** Indirection to Sdks for testing purposes. */
+public interface BlazeSdkProvider {
+ static BlazeSdkProvider getInstance() {
+ return ServiceManager.getService(BlazeSdkProvider.class);
+ }
+
+ List<Sdk> getAllAndroidSdks();
+
+ Sdk findSdk(String targetHash);
+
+ @Nullable
+ String getSdkTargetHash(Sdk sdk);
+}
diff --git a/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProviderImpl.java b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProviderImpl.java
new file mode 100644
index 0000000..d4c81ee
--- /dev/null
+++ b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProviderImpl.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017 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.android.sdk;
+
+import com.google.idea.blaze.android.compatibility.Compatibility.AndroidSdkUtils;
+import com.intellij.openapi.projectRoots.Sdk;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.jetbrains.android.sdk.AndroidSdkAdditionalData;
+
+/** Indirection to Sdks for testing purposes. */
+public class BlazeSdkProviderImpl implements BlazeSdkProvider {
+ @Override
+ public List<Sdk> getAllAndroidSdks() {
+ return AndroidSdkUtils.getAllAndroidSdks();
+ }
+
+ @Override
+ public Sdk findSdk(String targetHash) {
+ return AndroidSdkUtils.findSuitableAndroidSdk(targetHash);
+ }
+
+ @Override
+ @Nullable
+ public String getSdkTargetHash(Sdk sdk) {
+ AndroidSdkAdditionalData additionalData = AndroidSdkUtils.getAndroidSdkAdditionalData(sdk);
+ if (additionalData == null) {
+ return null;
+ }
+ return additionalData.getBuildTargetHashString();
+ }
+}
diff --git a/aswb/src/com/google/idea/blaze/android/sdk/MockBlazeSdkProvider.java b/aswb/src/com/google/idea/blaze/android/sdk/MockBlazeSdkProvider.java
new file mode 100644
index 0000000..2a97716
--- /dev/null
+++ b/aswb/src/com/google/idea/blaze/android/sdk/MockBlazeSdkProvider.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017 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.android.sdk;
+
+import com.google.common.collect.Maps;
+import com.intellij.openapi.projectRoots.Sdk;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.annotation.Nullable;
+
+/** Indirection to Sdks for testing purposes. */
+public class MockBlazeSdkProvider implements BlazeSdkProvider {
+ Map<String, Sdk> sdks = Maps.newHashMap();
+
+ public void addSdk(String targetHash, Sdk sdk) {
+ sdks.put(targetHash, sdk);
+ }
+
+ @Override
+ public List<Sdk> getAllAndroidSdks() {
+ return new ArrayList<>(sdks.values());
+ }
+
+ @Override
+ public Sdk findSdk(String targetHash) {
+ return sdks.get(targetHash);
+ }
+
+ @Override
+ @Nullable
+ public String getSdkTargetHash(Sdk sdk) {
+ return sdks.entrySet()
+ .stream()
+ .filter(entry -> entry.getValue() == sdk)
+ .map(Entry::getKey)
+ .findFirst()
+ .orElse(null);
+ }
+}
diff --git a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java
index bee4d9a..07db0d0 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java
@@ -17,12 +17,12 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidSdkUtils;
import com.google.idea.blaze.android.compatibility.Compatibility.IdeSdks;
import com.google.idea.blaze.android.cppapi.NdkSupport;
import com.google.idea.blaze.android.projectview.AndroidMinSdkSection;
import com.google.idea.blaze.android.projectview.AndroidSdkPlatformSection;
import com.google.idea.blaze.android.projectview.GeneratedAndroidResourcesSection;
+import com.google.idea.blaze.android.sdk.BlazeSdkProvider;
import com.google.idea.blaze.android.sync.importer.BlazeAndroidWorkspaceImporter;
import com.google.idea.blaze.android.sync.model.AndroidSdkPlatform;
import com.google.idea.blaze.android.sync.model.BlazeAndroidImportResult;
@@ -111,6 +111,10 @@
@Override
public void installSdks(BlazeContext context) {
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ return;
+ }
+
File path = IdeSdks.getAndroidSdkPath();
if (path != null) {
context.output(new StatusOutput("Installing SDK platforms..."));
@@ -176,7 +180,7 @@
if (androidSdkPlatform == null) {
return;
}
- Sdk sdk = AndroidSdkUtils.findSuitableAndroidSdk(androidSdkPlatform.androidSdk);
+ Sdk sdk = BlazeSdkProvider.getInstance().findSdk(androidSdkPlatform.androidSdk);
if (sdk == null) {
IssueOutput.error(
String.format("Android platform '%s' not found.", androidSdkPlatform.androidSdk))
diff --git a/aswb/src/com/google/idea/blaze/android/sync/sdk/AndroidSdkFromProjectView.java b/aswb/src/com/google/idea/blaze/android/sync/sdk/AndroidSdkFromProjectView.java
index b47e238..c4eb537 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/sdk/AndroidSdkFromProjectView.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/sdk/AndroidSdkFromProjectView.java
@@ -18,9 +18,9 @@
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidSdkUtils;
import com.google.idea.blaze.android.projectview.AndroidMinSdkSection;
import com.google.idea.blaze.android.projectview.AndroidSdkPlatformSection;
+import com.google.idea.blaze.android.sdk.BlazeSdkProvider;
import com.google.idea.blaze.android.sync.model.AndroidSdkPlatform;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.ProjectViewSet.ProjectViewFile;
@@ -40,7 +40,7 @@
@Nullable
public static AndroidSdkPlatform getAndroidSdkPlatform(
BlazeContext context, ProjectViewSet projectViewSet) {
- Collection<Sdk> sdks = AndroidSdkUtils.getAllAndroidSdks();
+ List<Sdk> sdks = BlazeSdkProvider.getInstance().getAllAndroidSdks();
if (sdks.isEmpty()) {
IssueOutput.error("No Android SDK configured. Please use the SDK manager to configure.")
.navigatable(
@@ -81,7 +81,7 @@
return null;
}
- Sdk sdk = AndroidSdkUtils.findSuitableAndroidSdk(androidSdk);
+ Sdk sdk = BlazeSdkProvider.getInstance().findSdk(androidSdk);
if (sdk == null) {
ProjectViewFile projectViewFile = projectViewSet.getTopLevelProjectViewFile();
IssueOutput.error(
@@ -104,19 +104,10 @@
return new AndroidSdkPlatform(androidSdk, androidMinSdk);
}
- @Nullable
- public static String getSdkTargetHash(Sdk sdk) {
- AndroidSdkAdditionalData additionalData = AndroidSdkUtils.getAndroidSdkAdditionalData(sdk);
- if (additionalData == null) {
- return null;
- }
- return additionalData.getBuildTargetHashString();
- }
-
public static List<String> getAvailableSdkTargetHashes(Collection<Sdk> sdks) {
Set<String> names = Sets.newHashSet();
for (Sdk sdk : sdks) {
- String targetHash = getSdkTargetHash(sdk);
+ String targetHash = BlazeSdkProvider.getInstance().getSdkTargetHash(sdk);
if (targetHash != null) {
names.add(targetHash);
}
diff --git a/aswb/src/com/google/idea/blaze/android/sync/sdk/SdkUtil.java b/aswb/src/com/google/idea/blaze/android/sync/sdk/SdkUtil.java
index fcbe1f9..885b931 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/sdk/SdkUtil.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/sdk/SdkUtil.java
@@ -16,7 +16,7 @@
package com.google.idea.blaze.android.sync.sdk;
import com.android.tools.idea.updater.configure.SdkUpdaterConfigurableProvider;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidSdkUtils;
+import com.google.idea.blaze.android.sdk.BlazeSdkProvider;
import com.google.idea.blaze.android.sync.model.AndroidSdkPlatform;
import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData;
import com.google.idea.blaze.base.model.BlazeProjectData;
@@ -49,7 +49,7 @@
if (androidSdkPlatform == null) {
return null;
}
- Sdk sdk = AndroidSdkUtils.findSuitableAndroidSdk(androidSdkPlatform.androidSdk);
+ Sdk sdk = BlazeSdkProvider.getInstance().findSdk(androidSdkPlatform.androidSdk);
if (sdk == null) {
return null;
}
diff --git a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateMigrationTest.java b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateMigrationTest.java
index 7eca0c6..50786f9 100644
--- a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateMigrationTest.java
+++ b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateMigrationTest.java
@@ -18,14 +18,18 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.idea.blaze.android.BlazeAndroidIntegrationTestCase;
+import com.google.idea.blaze.android.AndroidIntegrationTestCleanupHelper;
+import com.google.idea.blaze.android.AndroidIntegrationTestSetupRule;
+import com.google.idea.blaze.base.BlazeIntegrationTestCase;
import java.io.StringReader;
import java.util.List;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
+import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -36,8 +40,7 @@
* migration code in BlazeAndroidRunConfigurationCommonState is removed.
*/
@RunWith(JUnit4.class)
-public class BlazeAndroidRunConfigurationCommonStateMigrationTest
- extends BlazeAndroidIntegrationTestCase {
+public class BlazeAndroidRunConfigurationCommonStateMigrationTest extends BlazeIntegrationTestCase {
private static final String DEPLOY_TARGET_STATES_RAW_XML =
"<android-deploy-target-states>"
@@ -71,6 +74,9 @@
+ " <option name=\"WORKING_DIR\" value=\"/some/other/directory\" />"
+ " <option name=\"TARGET_LOGGING_CHANNELS\" value=\"some other channels\" />"
+ "</BlazeAuto>";
+ @Rule
+ public final AndroidIntegrationTestSetupRule androidSetupRule =
+ new AndroidIntegrationTestSetupRule();
private BlazeAndroidRunConfigurationCommonState state;
private SAXBuilder saxBuilder;
@@ -83,6 +89,11 @@
xmlOutputter = new XMLOutputter(Format.getCompactFormat());
}
+ @After
+ public final void doTeardown() {
+ AndroidIntegrationTestCleanupHelper.cleanUp(getProject());
+ }
+
private String formatRawXml(String rawXml) throws Exception {
Element element =
saxBuilder.build(new StringReader("<?xml version=\"1.0\"?>" + rawXml)).getRootElement();
diff --git a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateTest.java b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateTest.java
index 1964580..8844355 100644
--- a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateTest.java
+++ b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateTest.java
@@ -19,8 +19,10 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.android.BlazeAndroidIntegrationTestCase;
+import com.google.idea.blaze.android.AndroidIntegrationTestCleanupHelper;
+import com.google.idea.blaze.android.AndroidIntegrationTestSetupRule;
import com.google.idea.blaze.android.cppapi.NdkSupport;
+import com.google.idea.blaze.base.BlazeIntegrationTestCase;
import com.google.idea.common.experiments.ExperimentService;
import com.google.idea.common.experiments.MockExperimentService;
import com.intellij.openapi.util.InvalidDataException;
@@ -28,15 +30,20 @@
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
+import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for {@link BlazeAndroidRunConfigurationCommonState}. */
@RunWith(JUnit4.class)
-public class BlazeAndroidRunConfigurationCommonStateTest extends BlazeAndroidIntegrationTestCase {
+public class BlazeAndroidRunConfigurationCommonStateTest extends BlazeIntegrationTestCase {
+ @Rule
+ public final AndroidIntegrationTestSetupRule androidSetupRule =
+ new AndroidIntegrationTestSetupRule();
private BlazeAndroidRunConfigurationCommonState state;
@Before
@@ -50,6 +57,11 @@
state = new BlazeAndroidRunConfigurationCommonState(buildSystem().getName(), false);
}
+ @After
+ public final void doTeardown() {
+ AndroidIntegrationTestCleanupHelper.cleanUp(getProject());
+ }
+
@Test
public void readAndWriteShouldMatch() throws InvalidDataException, WriteExternalException {
state.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
diff --git a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationStateTest.java b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationStateTest.java
index 05de9a5..1e55ac2 100644
--- a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationStateTest.java
+++ b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationStateTest.java
@@ -19,9 +19,11 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.android.BlazeAndroidIntegrationTestCase;
+import com.google.idea.blaze.android.AndroidIntegrationTestCleanupHelper;
+import com.google.idea.blaze.android.AndroidIntegrationTestSetupRule;
import com.google.idea.blaze.android.cppapi.NdkSupport;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState;
+import com.google.idea.blaze.base.BlazeIntegrationTestCase;
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.google.idea.common.experiments.ExperimentService;
import com.google.idea.common.experiments.MockExperimentService;
@@ -31,15 +33,20 @@
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
+import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for {@link BlazeAndroidBinaryRunConfigurationState}. */
@RunWith(JUnit4.class)
-public class BlazeAndroidBinaryRunConfigurationStateTest extends BlazeAndroidIntegrationTestCase {
+public class BlazeAndroidBinaryRunConfigurationStateTest extends BlazeIntegrationTestCase {
+ @Rule
+ public final AndroidIntegrationTestSetupRule androidSetupRule =
+ new AndroidIntegrationTestSetupRule();
private BlazeAndroidBinaryRunConfigurationState state;
@Before
@@ -53,6 +60,11 @@
state = new BlazeAndroidBinaryRunConfigurationState(buildSystem().getName());
}
+ @After
+ public final void doTeardown() {
+ AndroidIntegrationTestCleanupHelper.cleanUp(getProject());
+ }
+
@Test
public void readAndWriteShouldMatch() throws InvalidDataException, WriteExternalException {
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
diff --git a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationStateTest.java b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationStateTest.java
index f04a14e..1085d2b 100644
--- a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationStateTest.java
+++ b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationStateTest.java
@@ -18,9 +18,11 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.android.BlazeAndroidIntegrationTestCase;
+import com.google.idea.blaze.android.AndroidIntegrationTestCleanupHelper;
+import com.google.idea.blaze.android.AndroidIntegrationTestSetupRule;
import com.google.idea.blaze.android.cppapi.NdkSupport;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState;
+import com.google.idea.blaze.base.BlazeIntegrationTestCase;
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.google.idea.common.experiments.ExperimentService;
import com.google.idea.common.experiments.MockExperimentService;
@@ -30,15 +32,20 @@
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
+import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for {@link BlazeAndroidTestRunConfigurationState}. */
@RunWith(JUnit4.class)
-public class BlazeAndroidTestRunConfigurationStateTest extends BlazeAndroidIntegrationTestCase {
+public class BlazeAndroidTestRunConfigurationStateTest extends BlazeIntegrationTestCase {
+ @Rule
+ public final AndroidIntegrationTestSetupRule androidSetupRule =
+ new AndroidIntegrationTestSetupRule();
private BlazeAndroidTestRunConfigurationState state;
@Before
@@ -52,6 +59,11 @@
state = new BlazeAndroidTestRunConfigurationState(buildSystem().getName());
}
+ @After
+ public final void doTeardown() {
+ AndroidIntegrationTestCleanupHelper.cleanUp(getProject());
+ }
+
@Test
public void readAndWriteShouldMatch() throws InvalidDataException, WriteExternalException {
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
diff --git a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/test/smrunner/BlazeAndroidTestEventsHandlerTest.java b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/test/smrunner/BlazeAndroidTestEventsHandlerTest.java
index 474e1b4..2a4bf02 100644
--- a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/test/smrunner/BlazeAndroidTestEventsHandlerTest.java
+++ b/aswb/tests/integrationtests/com/google/idea/blaze/android/run/test/smrunner/BlazeAndroidTestEventsHandlerTest.java
@@ -18,7 +18,9 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.Iterables;
-import com.google.idea.blaze.android.BlazeAndroidIntegrationTestCase;
+import com.google.idea.blaze.android.AndroidIntegrationTestCleanupHelper;
+import com.google.idea.blaze.android.AndroidIntegrationTestSetupRule;
+import com.google.idea.blaze.base.BlazeIntegrationTestCase;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.intellij.execution.Location;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -28,15 +30,20 @@
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import javax.annotation.Nullable;
+import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Integration tests for {@link BlazeAndroidTestEventsHandler}. */
@RunWith(JUnit4.class)
-public class BlazeAndroidTestEventsHandlerTest extends BlazeAndroidIntegrationTestCase {
+public class BlazeAndroidTestEventsHandlerTest extends BlazeIntegrationTestCase {
+ @Rule
+ public final AndroidIntegrationTestSetupRule androidSetupRule =
+ new AndroidIntegrationTestSetupRule();
private final BlazeAndroidTestEventsHandler handler = new BlazeAndroidTestEventsHandler();
@Before
@@ -56,6 +63,11 @@
"public class JUnit4 {}");
}
+ @After
+ public final void doTeardown() {
+ AndroidIntegrationTestCleanupHelper.cleanUp(getProject());
+ }
+
@Test
public void testSuiteLocationResolves() {
PsiFile javaFile =
diff --git a/aswb/tests/integrationtests/com/google/idea/blaze/android/sync/AndroidSyncTest.java b/aswb/tests/integrationtests/com/google/idea/blaze/android/sync/AndroidSyncTest.java
new file mode 100644
index 0000000..6e5a68d
--- /dev/null
+++ b/aswb/tests/integrationtests/com/google/idea/blaze/android/sync/AndroidSyncTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2017 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.android.sync;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.android.AndroidIntegrationTestCleanupHelper;
+import com.google.idea.blaze.android.AndroidIntegrationTestSetupRule;
+import com.google.idea.blaze.android.sdk.BlazeSdkProvider;
+import com.google.idea.blaze.android.sdk.MockBlazeSdkProvider;
+import com.google.idea.blaze.base.ideinfo.AndroidIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TargetMap;
+import com.google.idea.blaze.base.ideinfo.TargetMapBuilder;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.model.primitives.WorkspaceType;
+import com.google.idea.blaze.base.sync.BlazeSyncIntegrationTestCase;
+import com.google.idea.blaze.base.sync.BlazeSyncParams;
+import com.google.idea.blaze.base.sync.BlazeSyncParams.SyncMode;
+import com.google.idea.blaze.base.sync.data.BlazeDataStorage;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.android.facet.AndroidFacet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Android-specific sync integration tests. */
+@RunWith(JUnit4.class)
+public class AndroidSyncTest extends BlazeSyncIntegrationTestCase {
+
+ @Rule
+ public final AndroidIntegrationTestSetupRule androidSetupRule =
+ new AndroidIntegrationTestSetupRule();
+
+ @Before
+ public void setup() {
+ mockSdk("android-25", "Android 25 SDK");
+ }
+
+ @After
+ public final void doTeardown() {
+ AndroidIntegrationTestCleanupHelper.cleanUp(getProject());
+ }
+
+ private void mockSdk(String targetHash, String sdkName) {
+ SdkTypeId sdkType = mock(SdkTypeId.class);
+ when(sdkType.getName()).thenReturn("Android SDK");
+ Sdk sdk = mock(Sdk.class);
+ when(sdk.getName()).thenReturn(sdkName);
+ when(sdk.getSdkType()).thenReturn(sdkType);
+ MockBlazeSdkProvider sdkProvider = (MockBlazeSdkProvider) BlazeSdkProvider.getInstance();
+ sdkProvider.addSdk(targetHash, sdk);
+ }
+
+ @Test
+ public void testSimpleSync() throws Exception {
+ setProjectView(
+ "directories:",
+ " java/com/google",
+ "targets:",
+ " //java/com/google:lib",
+ "android_sdk_platform: android-25");
+
+ workspace.createFile(
+ new WorkspacePath("java/com/google/Source.java"),
+ "package com.google;",
+ "public class Source {}");
+
+ workspace.createFile(
+ new WorkspacePath("java/com/google/Other.java"),
+ "package com.google;",
+ "public class Other {}");
+
+ VirtualFile javaRoot = workspace.createDirectory(new WorkspacePath("java/com/google"));
+
+ TargetMap targetMap =
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setBuildFile(sourceRoot("java/com/google/BUILD"))
+ .setLabel("//java/com/google:lib")
+ .setKind("android_library")
+ .setAndroidInfo(
+ AndroidIdeInfo.builder()
+ .setManifestFile(sourceRoot("java/com/google/AndroidManifest.xml"))
+ .addResource(sourceRoot("java/com/google/res/values/strings.xml"))
+ .setGenerateResourceClass(true))
+ .addSource(sourceRoot("java/com/google/Source.java"))
+ .addSource(sourceRoot("java/com/google/Other.java")))
+ .build();
+
+ setTargetMap(targetMap);
+
+ runBlazeSync(
+ new BlazeSyncParams.Builder("Sync", SyncMode.INCREMENTAL)
+ .addProjectViewTargets(true)
+ .build());
+
+ errorCollector.assertNoIssues();
+
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(getProject()).getBlazeProjectData();
+ assertThat(blazeProjectData).isNotNull();
+ assertThat(blazeProjectData.targetMap).isEqualTo(targetMap);
+ assertThat(blazeProjectData.workspaceLanguageSettings.getWorkspaceType())
+ .isEqualTo(WorkspaceType.ANDROID);
+
+ ImmutableList<ContentEntry> contentEntries = getWorkspaceContentEntries();
+ assertThat(contentEntries).hasSize(1);
+ assertThat(findContentEntry(javaRoot)).isNotNull();
+ assertThat(findContentEntry(javaRoot).getSourceFolders()).hasLength(1);
+
+ // Check that the workspace is set to android
+ Module workspaceModule = getModuleCreatedDuringSync(BlazeDataStorage.WORKSPACE_MODULE_NAME);
+ assertThat(workspaceModule).isNotNull();
+ assertThat(AndroidFacet.getInstance(workspaceModule)).isNotNull();
+
+ // Check that a resource module was created
+ Module resourceModule = getModuleCreatedDuringSync("java.com.google.lib");
+ assertThat(resourceModule).isNotNull();
+ assertThat(AndroidFacet.getInstance(resourceModule)).isNotNull();
+ }
+}
diff --git a/aswb/tests/unittests/com/google/idea/blaze/android/sync/importer/BlazeAndroidWorkspaceImporterTest.java b/aswb/tests/unittests/com/google/idea/blaze/android/sync/importer/BlazeAndroidWorkspaceImporterTest.java
index c839293..2301f3a 100644
--- a/aswb/tests/unittests/com/google/idea/blaze/android/sync/importer/BlazeAndroidWorkspaceImporterTest.java
+++ b/aswb/tests/unittests/com/google/idea/blaze/android/sync/importer/BlazeAndroidWorkspaceImporterTest.java
@@ -95,8 +95,7 @@
BlazeExecutor blazeExecutor = new MockBlazeExecutor();
applicationServices.register(BlazeExecutor.class, blazeExecutor);
- projectServices.register(
- BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
+ projectServices.register(BlazeImportSettingsManager.class, new BlazeImportSettingsManager());
BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
MockFileAttributeProvider mockFileAttributeProvider = new MockFileAttributeProvider();
diff --git a/base/BUILD b/base/BUILD
index 850f1dd..7afe714 100644
--- a/base/BUILD
+++ b/base/BUILD
@@ -11,7 +11,7 @@
"//common/experiments",
"//common/formatter",
"//intellij_platform_sdk:plugin_api",
- "//proto_deps",
+ "//proto:proto_deps",
"//sdkcompat",
"@jsr305_annotations//jar",
],
@@ -46,7 +46,7 @@
":unit_test_utils",
"//base",
"//intellij_platform_sdk:plugin_api_for_tests",
- "//proto_deps",
+ "//proto:proto_deps",
"//testing:lib",
"@jsr305_annotations//jar",
"@junit//jar",
@@ -91,7 +91,7 @@
"//common/experiments",
"//common/experiments:unit_test_utils",
"//intellij_platform_sdk:plugin_api_for_tests",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
"@junit//jar",
],
@@ -110,7 +110,7 @@
":integration_test_utils",
":unit_test_utils",
"//intellij_platform_sdk:plugin_api_for_tests",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
"@junit//jar",
],
diff --git a/base/src/META-INF/blaze-base.xml b/base/src/META-INF/blaze-base.xml
index 913bdb5..781e35a 100644
--- a/base/src/META-INF/blaze-base.xml
+++ b/base/src/META-INF/blaze-base.xml
@@ -183,7 +183,6 @@
<projectService serviceInterface="com.google.idea.blaze.base.targetmaps.TransitiveDependencyMap"
serviceImplementation="com.google.idea.blaze.base.targetmaps.TransitiveDependencyMap"/>
<projectService serviceImplementation="com.google.idea.blaze.base.settings.BlazeImportSettingsManager"/>
- <projectService serviceImplementation="com.google.idea.blaze.base.settings.BlazeImportSettingsManagerLegacy"/>
<applicationService serviceImplementation="com.google.idea.blaze.base.settings.BlazeUserSettings"/>
<applicationService serviceInterface="com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpecProvider"
serviceImplementation="com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpecProviderImpl"/>
@@ -233,10 +232,11 @@
<!--<annotator language="BUILD" implementationClass="com.google.idea.blaze.base.lang.buildfile.validation.LoadErrorAnnotator"/>-->
<annotator language="BUILD" implementationClass="com.google.idea.blaze.base.lang.buildfile.validation.GlobErrorAnnotator"/>
<annotator language="BUILD" implementationClass="com.google.idea.blaze.base.lang.buildfile.validation.BuiltInRuleAnnotator"/>
+ <annotator language="BUILD" implementationClass="com.google.idea.blaze.base.lang.buildfile.validation.LoadStatementAnnotator"/>
<colorSettingsPage implementation="com.google.idea.blaze.base.lang.buildfile.highlighting.BuildColorsPage"/>
<projectService serviceImplementation="com.google.idea.blaze.base.lang.buildfile.psi.util.BuildElementGenerator"/>
<projectService serviceImplementation="com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager"/>
- <referencesSearch implementation="com.google.idea.blaze.base.lang.buildfile.search.BuildLabelReferenceSearcher"/>
+ <referencesSearch implementation="com.google.idea.blaze.base.lang.buildfile.search.BuildReferenceSearcher"/>
<referencesSearch implementation="com.google.idea.blaze.base.lang.buildfile.search.GlobReferenceSearcher"/>
<readWriteAccessDetector implementation="com.google.idea.blaze.base.lang.buildfile.findusages.BuildReadWriteAccessDetector"/>
<elementDescriptionProvider implementation="com.google.idea.blaze.base.lang.buildfile.findusages.BuildElementDescriptionProvider"/>
@@ -340,6 +340,7 @@
<BuildifierBinaryProvider implementation="com.google.idea.blaze.base.buildmodifier.BazelBuildifierBinaryProvider"/>
<BlazeCommandRunConfigurationHandlerProvider implementation="com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandlerProvider" order="last"/>
<TestTargetHeuristic implementation="com.google.idea.blaze.base.run.TargetNameHeuristic" order="first"/>
+ <TestTargetHeuristic implementation="com.google.idea.blaze.base.run.TestTargetSourcesHeuristic" order="before TestSizeHeuristic" id="TestSourcesHeuristic"/>
<TestTargetHeuristic implementation="com.google.idea.blaze.base.run.TestSizeHeuristic" order="last" id="TestSizeHeuristic"/>
<RunConfigurationFactory implementation="com.google.idea.blaze.base.run.BlazeBuildTargetRunConfigurationFactory" order="last"/>
<AspectStrategyProvider implementation="com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategyProviderBazel" order="last"/>
diff --git a/base/src/com/google/idea/blaze/base/async/executor/BlazeExecutor.java b/base/src/com/google/idea/blaze/base/async/executor/BlazeExecutor.java
index f9eed17..8df0ed0 100644
--- a/base/src/com/google/idea/blaze/base/async/executor/BlazeExecutor.java
+++ b/base/src/com/google/idea/blaze/base/async/executor/BlazeExecutor.java
@@ -28,8 +28,8 @@
import com.intellij.openapi.util.Computable;
import com.intellij.util.ui.UIUtil;
import java.util.concurrent.Callable;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Shared thread pool for blaze tasks. */
public abstract class BlazeExecutor {
@@ -59,7 +59,7 @@
@NotNull final String title,
@NotNull final Progressive progressive) {
return submitTask(
- project, title, true /* cancelable */, Modality.ALWAYS_BACKGROUND, progressive);
+ project, title, /* cancelable */ true, Modality.ALWAYS_BACKGROUND, progressive);
}
public static ListenableFuture<Void> submitTask(
diff --git a/base/src/com/google/idea/blaze/base/bazel/BazelBuildSystemProvider.java b/base/src/com/google/idea/blaze/base/bazel/BazelBuildSystemProvider.java
index b3d4598..efb75be 100644
--- a/base/src/com/google/idea/blaze/base/bazel/BazelBuildSystemProvider.java
+++ b/base/src/com/google/idea/blaze/base/bazel/BazelBuildSystemProvider.java
@@ -22,6 +22,7 @@
import com.google.idea.blaze.base.model.BlazeVersionData;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
+import com.google.idea.blaze.base.settings.BlazeUserSettings;
import com.intellij.openapi.fileTypes.ExactFileNameMatcher;
import com.intellij.openapi.fileTypes.FileNameMatcher;
import java.io.File;
@@ -35,6 +36,13 @@
return BuildSystem.Bazel;
}
+ @Nullable
+ @Override
+ public String getBinaryPath() {
+ BlazeUserSettings settings = BlazeUserSettings.getInstance();
+ return settings.getBazelBinaryPath();
+ }
+
@Override
public WorkspaceRootProvider getWorkspaceRootProvider() {
return BazelWorkspaceRootProvider.INSTANCE;
@@ -65,15 +73,20 @@
public File findBuildFileInDirectory(File directory) {
FileAttributeProvider provider = FileAttributeProvider.getInstance();
File child = new File(directory, "BUILD");
- if (!provider.exists(child)) {
- return null;
+ if (provider.exists(child)) {
+ return child;
}
- return child;
+ child = new File(directory, "BUILD.bazel");
+ if (provider.exists(child)) {
+ return child;
+ }
+ return null;
}
@Override
- public FileNameMatcher buildFileMatcher() {
- return new ExactFileNameMatcher("BUILD");
+ public ImmutableList<FileNameMatcher> buildFileMatchers() {
+ return ImmutableList.of(
+ new ExactFileNameMatcher("BUILD"), new ExactFileNameMatcher("BUILD.bazel"));
}
@Override
diff --git a/base/src/com/google/idea/blaze/base/bazel/BuildSystemProvider.java b/base/src/com/google/idea/blaze/base/bazel/BuildSystemProvider.java
index 61c7257..eb20772 100644
--- a/base/src/com/google/idea/blaze/base/bazel/BuildSystemProvider.java
+++ b/base/src/com/google/idea/blaze/base/bazel/BuildSystemProvider.java
@@ -71,6 +71,16 @@
*/
BuildSystem buildSystem();
+ /** @return The location of the blaze/bazel binary. */
+ @Nullable
+ String getBinaryPath();
+
+ /** @return The location of the blaze/bazel binary to use for syncing. */
+ @Nullable
+ default String getSyncBinaryPath() {
+ return getBinaryPath();
+ }
+
WorkspaceRootProvider getWorkspaceRootProvider();
/** Directories containing artifacts produced during the build process. */
@@ -101,7 +111,7 @@
return buildFile != null ? directory.getFileSystem().findFileByPath(buildFile.getPath()) : null;
}
- FileNameMatcher buildFileMatcher();
+ ImmutableList<FileNameMatcher> buildFileMatchers();
/** Populates the passed builder with version data. */
void populateBlazeVersionData(
diff --git a/base/src/com/google/idea/blaze/base/buildmodifier/FileSystemModifier.java b/base/src/com/google/idea/blaze/base/buildmodifier/FileSystemModifier.java
index f3586a2..96719c1 100644
--- a/base/src/com/google/idea/blaze/base/buildmodifier/FileSystemModifier.java
+++ b/base/src/com/google/idea/blaze/base/buildmodifier/FileSystemModifier.java
@@ -19,8 +19,8 @@
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import java.io.File;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Modifies the file system. Interface so we can mock it in tests */
public abstract class FileSystemModifier {
diff --git a/base/src/com/google/idea/blaze/base/buildmodifier/FileSystemModifierImpl.java b/base/src/com/google/idea/blaze/base/buildmodifier/FileSystemModifierImpl.java
index 0d398f9..7e873ee 100644
--- a/base/src/com/google/idea/blaze/base/buildmodifier/FileSystemModifierImpl.java
+++ b/base/src/com/google/idea/blaze/base/buildmodifier/FileSystemModifierImpl.java
@@ -20,8 +20,8 @@
import com.intellij.openapi.project.Project;
import java.io.File;
import java.io.IOException;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
class FileSystemModifierImpl extends FileSystemModifier {
diff --git a/base/src/com/google/idea/blaze/base/command/BlazeCommand.java b/base/src/com/google/idea/blaze/base/command/BlazeCommand.java
index a337472..41e40e8 100644
--- a/base/src/com/google/idea/blaze/base/command/BlazeCommand.java
+++ b/base/src/com/google/idea/blaze/base/command/BlazeCommand.java
@@ -18,30 +18,21 @@
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
-import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
-import com.google.idea.blaze.base.settings.BlazeUserSettings;
import java.util.Arrays;
import java.util.List;
-import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/** A command to issue to Blaze/Bazel on the command line. */
@Immutable
public final class BlazeCommand {
- private final BuildSystem buildSystem;
+ private final String binaryPath;
private final BlazeCommandName name;
- @Nullable private final String blazeBinary;
private final ImmutableList<String> arguments;
- private BlazeCommand(
- BuildSystem buildSystem,
- BlazeCommandName name,
- @Nullable String blazeBinary,
- ImmutableList<String> arguments) {
- this.buildSystem = buildSystem;
+ private BlazeCommand(String binaryPath, BlazeCommandName name, ImmutableList<String> arguments) {
+ this.binaryPath = binaryPath;
this.name = name;
- this.blazeBinary = blazeBinary;
this.arguments = arguments;
}
@@ -50,49 +41,31 @@
}
public ImmutableList<String> toList() {
- String blazeBinary = this.blazeBinary;
- if (blazeBinary == null) {
- blazeBinary = getBinaryPath(buildSystem);
- }
-
ImmutableList.Builder<String> commandLine = ImmutableList.builder();
- commandLine.add(blazeBinary, name.toString());
+ commandLine.add(binaryPath, name.toString());
commandLine.addAll(arguments);
return commandLine.build();
}
- private static String getBinaryPath(BuildSystem buildSystem) {
- BlazeUserSettings settings = BlazeUserSettings.getInstance();
- switch (buildSystem) {
- case Blaze:
- return settings.getBlazeBinaryPath();
- case Bazel:
- return settings.getBazelBinaryPath();
- default:
- throw new RuntimeException("Unrecognized build system type: " + buildSystem);
- }
- }
-
@Override
public String toString() {
return Joiner.on(' ').join(toList());
}
- public static Builder builder(BuildSystem buildSystem, BlazeCommandName name) {
- return new Builder(buildSystem, name);
+ public static Builder builder(String binaryPath, BlazeCommandName name) {
+ return new Builder(binaryPath, name);
}
/** Builder for a blaze command */
public static class Builder {
- private final BuildSystem buildSystem;
+ private final String binaryPath;
private final BlazeCommandName name;
- @Nullable private String blazeBinary;
private final ImmutableList.Builder<TargetExpression> targets = ImmutableList.builder();
private final ImmutableList.Builder<String> blazeFlags = ImmutableList.builder();
private final ImmutableList.Builder<String> exeFlags = ImmutableList.builder();
- public Builder(BuildSystem buildSystem, BlazeCommandName name) {
- this.buildSystem = buildSystem;
+ public Builder(String binaryPath, BlazeCommandName name) {
+ this.binaryPath = binaryPath;
this.name = name;
// Tell forge what tool we used to call blaze so we can track usage.
addBlazeFlags(BlazeFlags.getToolTagFlag());
@@ -109,12 +82,7 @@
}
arguments.addAll(exeFlags.build());
- return new BlazeCommand(buildSystem, name, blazeBinary, arguments.build());
- }
-
- public Builder setBlazeBinary(@Nullable String blazeBinary) {
- this.blazeBinary = blazeBinary;
- return this;
+ return new BlazeCommand(binaryPath, name, arguments.build());
}
public Builder addTargets(TargetExpression... targets) {
diff --git a/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java b/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java
index 8d512c0..9698b62 100644
--- a/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java
+++ b/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java
@@ -29,7 +29,7 @@
private final List<File> fileList;
private final Predicate<String> filter;
- boolean insideBuildResult = false;
+ private boolean afterBuildResult = false;
public ExperimentalShowArtifactsLineProcessor(List<File> fileList) {
this(fileList, (value) -> true);
@@ -42,23 +42,17 @@
@Override
public boolean processLine(@NotNull String line) {
- if (insideBuildResult) {
- // Workaround for --experimental_ui: Extra newlines are inserted
- if (line.isEmpty()) {
- return false;
- }
-
- insideBuildResult = line.startsWith(OUTPUT_MARKER);
- if (insideBuildResult) {
- String fileName = line.substring(OUTPUT_MARKER.length());
- if (filter.test(fileName)) {
- fileList.add(new File(fileName));
- }
- }
+ if (!afterBuildResult) {
+ afterBuildResult = line.equals(OUTPUT_START);
+ return !afterBuildResult;
}
- if (!insideBuildResult) {
- insideBuildResult = line.equals(OUTPUT_START);
+ if (!line.startsWith(OUTPUT_MARKER)) {
+ return true;
}
- return !insideBuildResult;
+ String fileName = line.substring(OUTPUT_MARKER.length());
+ if (filter.test(fileName)) {
+ fileList.add(new File(fileName));
+ }
+ return false;
}
}
diff --git a/base/src/com/google/idea/blaze/base/command/info/BlazeInfo.java b/base/src/com/google/idea/blaze/base/command/info/BlazeInfo.java
index 1d329aa..a6666e9 100644
--- a/base/src/com/google/idea/blaze/base/command/info/BlazeInfo.java
+++ b/base/src/com/google/idea/blaze/base/command/info/BlazeInfo.java
@@ -22,7 +22,6 @@
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.intellij.openapi.components.ServiceManager;
import java.util.List;
-import javax.annotation.Nullable;
/** Runs the blaze info command. The results may be cached in the workspace. */
public abstract class BlazeInfo {
@@ -77,8 +76,8 @@
* @return The blaze info value associated with the specified key
*/
public abstract ListenableFuture<String> runBlazeInfo(
- @Nullable BlazeContext context,
- BuildSystem buildSystem,
+ BlazeContext context,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags,
String key);
@@ -89,24 +88,22 @@
* @return The blaze info value associated with the specified key
*/
public abstract ListenableFuture<byte[]> runBlazeInfoGetBytes(
- @Nullable BlazeContext context,
- BuildSystem buildSystem,
+ BlazeContext context,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags,
String key);
/**
* This calls blaze info without any specific key so blaze info will return all keys and values
- * that it has. There could be a performance cost for doing this, so the user should verify that
- * calling this method is actually faster than calling {@link #runBlazeInfo(WorkspaceRoot, List,
- * String)}.
+ * that it has.
*
* @param blazeFlags The blaze flags that will be passed to Blaze.
* @return The blaze info data fields.
*/
public abstract ListenableFuture<ImmutableMap<String, String>> runBlazeInfo(
- @Nullable BlazeContext context,
- BuildSystem buildSystem,
+ BlazeContext context,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags);
}
diff --git a/base/src/com/google/idea/blaze/base/command/info/BlazeInfoException.java b/base/src/com/google/idea/blaze/base/command/info/BlazeInfoException.java
index 39294c3..98aa7d3 100644
--- a/base/src/com/google/idea/blaze/base/command/info/BlazeInfoException.java
+++ b/base/src/com/google/idea/blaze/base/command/info/BlazeInfoException.java
@@ -17,33 +17,23 @@
import javax.annotation.concurrent.Immutable;
-/** Exception occuring during blaze infoy */
+/** Exception occuring during blaze info */
@Immutable
public final class BlazeInfoException extends Exception {
private final int exitCode;
private final String stdout;
- private final String stderr;
- public BlazeInfoException(int exitCode, String stdout, String stderr) {
+ public BlazeInfoException(int exitCode, String stdout) {
this.exitCode = exitCode;
this.stdout = stdout;
- this.stderr = stderr;
}
@Override
public String getMessage() {
- return "blaze info failed with exit code: " + exitCode + " and error stream: " + stderr;
- }
-
- public int getExitCode() {
- return exitCode;
+ return "blaze info failed with exit code: " + exitCode;
}
public String getStdout() {
return stdout;
}
-
- public String getStderr() {
- return stderr;
- }
}
diff --git a/base/src/com/google/idea/blaze/base/command/info/BlazeInfoImpl.java b/base/src/com/google/idea/blaze/base/command/info/BlazeInfoImpl.java
index 4b9fe6c..3410796 100644
--- a/base/src/com/google/idea/blaze/base/command/info/BlazeInfoImpl.java
+++ b/base/src/com/google/idea/blaze/base/command/info/BlazeInfoImpl.java
@@ -19,11 +19,12 @@
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.async.process.ExternalTask;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
+import com.google.idea.blaze.base.async.process.PrintOutputLineProcessor;
import com.google.idea.blaze.base.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
-import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.intellij.openapi.diagnostic.Logger;
import java.io.ByteArrayOutputStream;
import java.util.List;
@@ -34,42 +35,42 @@
@Override
public ListenableFuture<String> runBlazeInfo(
- @Nullable BlazeContext context,
- BuildSystem buildSystem,
+ BlazeContext context,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags,
String key) {
return BlazeExecutor.getInstance()
.submit(
() ->
- runBlazeInfo(buildSystem, workspaceRoot, key, blazeFlags, context)
+ runBlazeInfo(binaryPath, workspaceRoot, key, blazeFlags, context)
.toString()
.trim());
}
@Override
public ListenableFuture<byte[]> runBlazeInfoGetBytes(
- @Nullable BlazeContext context,
- BuildSystem buildSystem,
+ BlazeContext context,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags,
String key) {
return BlazeExecutor.getInstance()
.submit(
- () -> runBlazeInfo(buildSystem, workspaceRoot, key, blazeFlags, context).toByteArray());
+ () -> runBlazeInfo(binaryPath, workspaceRoot, key, blazeFlags, context).toByteArray());
}
@Override
public ListenableFuture<ImmutableMap<String, String>> runBlazeInfo(
- @Nullable BlazeContext context,
- BuildSystem buildSystem,
+ BlazeContext context,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags) {
return BlazeExecutor.getInstance()
.submit(
() -> {
String blazeInfoString =
- runBlazeInfo(buildSystem, workspaceRoot, null /* key */, blazeFlags, context)
+ runBlazeInfo(binaryPath, workspaceRoot, /* key */ null, blazeFlags, context)
.toString()
.trim();
return parseBlazeInfoResult(blazeInfoString);
@@ -77,29 +78,28 @@
}
private static ByteArrayOutputStream runBlazeInfo(
- BuildSystem buildSystem,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
@Nullable String key,
List<String> blazeFlags,
- @Nullable BlazeContext context)
+ BlazeContext context)
throws BlazeInfoException {
- BlazeCommand.Builder builder = BlazeCommand.builder(buildSystem, BlazeCommandName.INFO);
+ BlazeCommand.Builder builder = BlazeCommand.builder(binaryPath, BlazeCommandName.INFO);
if (key != null) {
builder.addBlazeFlags(key);
}
BlazeCommand command = builder.addBlazeFlags(blazeFlags).build();
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
- ByteArrayOutputStream stderr = new ByteArrayOutputStream();
int exitCode =
ExternalTask.builder(workspaceRoot)
.addBlazeCommand(command)
.context(context)
.stdout(stdout)
- .stderr(stderr)
+ .stderr(LineProcessingOutputStream.of(new PrintOutputLineProcessor(context)))
.build()
.run();
if (exitCode != 0) {
- throw new BlazeInfoException(exitCode, stdout.toString(), stderr.toString());
+ throw new BlazeInfoException(exitCode, stdout.toString());
}
return stdout;
}
diff --git a/base/src/com/google/idea/blaze/base/console/BlazeConsoleService.java b/base/src/com/google/idea/blaze/base/console/BlazeConsoleService.java
index 2bd7d57..2e40a53 100644
--- a/base/src/com/google/idea/blaze/base/console/BlazeConsoleService.java
+++ b/base/src/com/google/idea/blaze/base/console/BlazeConsoleService.java
@@ -18,8 +18,8 @@
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Prints text to the blaze console. */
public interface BlazeConsoleService {
diff --git a/base/src/com/google/idea/blaze/base/console/BlazeConsoleServiceImpl.java b/base/src/com/google/idea/blaze/base/console/BlazeConsoleServiceImpl.java
index ba5e3a6..5b4792b 100644
--- a/base/src/com/google/idea/blaze/base/console/BlazeConsoleServiceImpl.java
+++ b/base/src/com/google/idea/blaze/base/console/BlazeConsoleServiceImpl.java
@@ -19,8 +19,8 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Implementation for BlazeConsoleService */
public class BlazeConsoleServiceImpl implements BlazeConsoleService {
diff --git a/base/src/com/google/idea/blaze/base/console/BlazeConsoleView.java b/base/src/com/google/idea/blaze/base/console/BlazeConsoleView.java
index d5c02c3..58162c5 100644
--- a/base/src/com/google/idea/blaze/base/console/BlazeConsoleView.java
+++ b/base/src/com/google/idea/blaze/base/console/BlazeConsoleView.java
@@ -38,10 +38,10 @@
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import java.awt.BorderLayout;
+import javax.annotation.Nullable;
import javax.swing.JComponent;
import javax.swing.JPanel;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
class BlazeConsoleView implements Disposable {
diff --git a/base/src/com/google/idea/blaze/base/filecache/FileDiffer.java b/base/src/com/google/idea/blaze/base/filecache/FileDiffer.java
index 0142f06..052bb6e 100644
--- a/base/src/com/google/idea/blaze/base/filecache/FileDiffer.java
+++ b/base/src/com/google/idea/blaze/base/filecache/FileDiffer.java
@@ -23,7 +23,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Provides a diffing service for a collection of files. */
public final class FileDiffer {
diff --git a/base/src/com/google/idea/blaze/base/ide/NewBlazePackageDialog.java b/base/src/com/google/idea/blaze/base/ide/NewBlazePackageDialog.java
index 1f5d7c5..356b284 100644
--- a/base/src/com/google/idea/blaze/base/ide/NewBlazePackageDialog.java
+++ b/base/src/com/google/idea/blaze/base/ide/NewBlazePackageDialog.java
@@ -38,11 +38,11 @@
import java.awt.GridBagLayout;
import java.io.File;
import java.util.List;
+import javax.annotation.Nullable;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
class NewBlazePackageDialog extends DialogWrapper {
private static final Logger logger = Logger.getInstance(NewBlazePackageDialog.class);
diff --git a/base/src/com/google/idea/blaze/base/ide/NewRuleUI.java b/base/src/com/google/idea/blaze/base/ide/NewRuleUI.java
index 8f859fd..bf0c26a 100644
--- a/base/src/com/google/idea/blaze/base/ide/NewRuleUI.java
+++ b/base/src/com/google/idea/blaze/base/ide/NewRuleUI.java
@@ -27,9 +27,9 @@
import com.intellij.ui.components.JBTextField;
import java.util.Collection;
import java.util.List;
+import javax.annotation.Nullable;
import javax.swing.JPanel;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
final class NewRuleUI {
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/AndroidIdeInfo.java b/base/src/com/google/idea/blaze/base/ideinfo/AndroidIdeInfo.java
index 760fac7..68a7565 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/AndroidIdeInfo.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/AndroidIdeInfo.java
@@ -19,7 +19,7 @@
import com.google.idea.blaze.base.model.primitives.Label;
import java.io.Serializable;
import java.util.Collection;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Ide info specific to android rules. */
public final class AndroidIdeInfo implements Serializable {
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/JavaIdeInfo.java b/base/src/com/google/idea/blaze/base/ideinfo/JavaIdeInfo.java
index 174db51..271e390 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/JavaIdeInfo.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/JavaIdeInfo.java
@@ -18,7 +18,7 @@
import com.google.common.collect.ImmutableList;
import java.io.Serializable;
import java.util.Collection;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Ide info specific to java rules. */
public final class JavaIdeInfo implements Serializable {
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/LibraryArtifact.java b/base/src/com/google/idea/blaze/base/ideinfo/LibraryArtifact.java
index f661e5a..6eaab56 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/LibraryArtifact.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/LibraryArtifact.java
@@ -17,7 +17,7 @@
import com.google.common.base.Objects;
import java.io.Serializable;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Represents a jar artifact. */
public class LibraryArtifact implements Serializable {
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/TargetKey.java b/base/src/com/google/idea/blaze/base/ideinfo/TargetKey.java
index d1e99a1..9803427 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/TargetKey.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/TargetKey.java
@@ -24,7 +24,7 @@
import java.io.Serializable;
import java.util.List;
-/** A key that uniquely idenfifies a target in the target map */
+/** A key that uniquely identifies a target in the target map */
public class TargetKey implements Serializable, Comparable<TargetKey> {
private static final long serialVersionUID = 3L;
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/CompletionResultsProcessor.java b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/CompletionResultsProcessor.java
index c5a32e5..b9e6172 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/CompletionResultsProcessor.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/CompletionResultsProcessor.java
@@ -32,10 +32,13 @@
private final Map<String, LookupElement> results = Maps.newHashMap();
private final PsiElement originalElement;
private final QuoteType quoteType;
+ private final boolean allowPrivateSymbols;
- public CompletionResultsProcessor(PsiElement originalElement, QuoteType quoteType) {
+ public CompletionResultsProcessor(
+ PsiElement originalElement, QuoteType quoteType, boolean allowPrivateSymbols) {
this.originalElement = originalElement;
this.quoteType = quoteType;
+ this.allowPrivateSymbols = allowPrivateSymbols;
}
@Override
@@ -49,9 +52,11 @@
results.put(string, new LoadedSymbolReferenceLookupElement(loadedSymbol, string, quoteType));
} else if (buildElement instanceof PsiNamedElement) {
PsiNamedElement namedElement = (PsiNamedElement) buildElement;
- results.put(
- namedElement.getName(),
- new NamedBuildLookupElement((PsiNamedElement) buildElement, quoteType));
+ String name = namedElement.getName();
+ if (!allowPrivateSymbols && name != null && name.startsWith("_")) {
+ return true;
+ }
+ results.put(name, new NamedBuildLookupElement((PsiNamedElement) buildElement, quoteType));
}
return true;
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/FilterPatterns.java b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/FilterPatterns.java
deleted file mode 100644
index d888efb..0000000
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/FilterPatterns.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.completion;
-
-import static com.intellij.patterns.PlatformPatterns.psiElement;
-
-import com.intellij.patterns.ElementPattern;
-import com.intellij.patterns.PatternCondition;
-import com.intellij.psi.PsiElement;
-import com.intellij.util.ProcessingContext;
-import org.jetbrains.annotations.NotNull;
-
-/** Filter patterns used by completion contributors. */
-public class FilterPatterns {
-
- public static final ElementPattern<PsiElement> indexInParentsChildren(final int childIndex) {
- return psiElement()
- .with(
- new PatternCondition<PsiElement>("isIndexInParentsChildren") {
- @Override
- public boolean accepts(@NotNull PsiElement psiElement, ProcessingContext context) {
- final PsiElement parent = psiElement.getParent();
- if (parent != null) {
- final PsiElement[] children = parent.getChildren();
- if (childIndex < children.length && psiElement.equals(children[childIndex])) {
- return true;
- }
- }
- return false;
- }
- });
- }
-}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/findusages/BuildTargetElementEvaluator.java b/base/src/com/google/idea/blaze/base/lang/buildfile/findusages/BuildTargetElementEvaluator.java
index 7ef9399..a538b35 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/findusages/BuildTargetElementEvaluator.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/findusages/BuildTargetElementEvaluator.java
@@ -56,35 +56,32 @@
}
private static final Comparator<PsiReference> COMPARATOR =
- new Comparator<PsiReference>() {
- @Override
- public int compare(final PsiReference ref1, final PsiReference ref2) {
- boolean resolves1 = ref1.resolve() != null;
- boolean resolves2 = ref2.resolve() != null;
- if (resolves1 && !resolves2) {
- return -1;
- }
- if (!resolves1 && resolves2) {
- return 1;
- }
+ (ref1, ref2) -> {
+ boolean resolves1 = ref1.resolve() != null;
+ boolean resolves2 = ref2.resolve() != null;
+ if (resolves1 && !resolves2) {
+ return -1;
+ }
+ if (!resolves1 && resolves2) {
+ return 1;
+ }
- final TextRange range1 = ref1.getRangeInElement();
- final TextRange range2 = ref2.getRangeInElement();
+ final TextRange range1 = ref1.getRangeInElement();
+ final TextRange range2 = ref2.getRangeInElement();
- if (TextRange.areSegmentsEqual(range1, range2)) {
- return 0;
- }
- if (range1.getStartOffset() >= range2.getStartOffset()
- && range1.getEndOffset() <= range2.getEndOffset()) {
- return 1;
- }
- if (range2.getStartOffset() >= range1.getStartOffset()
- && range2.getEndOffset() <= range1.getEndOffset()) {
- return -1;
- }
-
+ if (TextRange.areSegmentsEqual(range1, range2)) {
return 0;
}
+ if (range1.getStartOffset() >= range2.getStartOffset()
+ && range1.getEndOffset() <= range2.getEndOffset()) {
+ return 1;
+ }
+ if (range2.getStartOffset() >= range1.getStartOffset()
+ && range2.getEndOffset() <= range1.getEndOffset()) {
+ return -1;
+ }
+
+ return 0;
};
/** Redirect 'name' funcall argument values to the funcall expression (b/29088829). */
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/formatting/BuildCommenter.java b/base/src/com/google/idea/blaze/base/lang/buildfile/formatting/BuildCommenter.java
index 34af8b9..994107e 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/formatting/BuildCommenter.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/formatting/BuildCommenter.java
@@ -20,7 +20,7 @@
import com.intellij.lang.CodeDocumentationAwareCommenter;
import com.intellij.psi.PsiComment;
import com.intellij.psi.tree.IElementType;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Supports (un)commenting lines via IntelliJ */
public class BuildCommenter implements CodeDocumentationAwareCommenter {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/formatting/BuildLanguageCodeStyleSettingsProvider.java b/base/src/com/google/idea/blaze/base/lang/buildfile/formatting/BuildLanguageCodeStyleSettingsProvider.java
index b2295af..2562a55 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/formatting/BuildLanguageCodeStyleSettingsProvider.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/formatting/BuildLanguageCodeStyleSettingsProvider.java
@@ -21,8 +21,8 @@
import com.intellij.lang.Language;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Allows BUILD language-specific code style settings */
public class BuildLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/language/BuildFileTypeFactory.java b/base/src/com/google/idea/blaze/base/lang/buildfile/language/BuildFileTypeFactory.java
index 4c4a21c..e975e61 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/language/BuildFileTypeFactory.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/language/BuildFileTypeFactory.java
@@ -15,8 +15,10 @@
*/
package com.google.idea.blaze.base.lang.buildfile.language;
+import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.intellij.openapi.fileTypes.ExtensionFileNameMatcher;
+import com.intellij.openapi.fileTypes.FileNameMatcher;
import com.intellij.openapi.fileTypes.FileTypeConsumer;
import com.intellij.openapi.fileTypes.FileTypeFactory;
import org.jetbrains.annotations.NotNull;
@@ -26,9 +28,11 @@
@Override
public void createFileTypes(@NotNull final FileTypeConsumer consumer) {
- consumer.consume(
- BuildFileType.INSTANCE,
- BuildSystemProvider.defaultBuildSystem().buildFileMatcher(),
- new ExtensionFileNameMatcher("bzl"));
+ ImmutableList<FileNameMatcher> fileNameMatchers =
+ ImmutableList.<FileNameMatcher>builder()
+ .addAll(BuildSystemProvider.defaultBuildSystem().buildFileMatchers())
+ .add(new ExtensionFileNameMatcher("bzl"))
+ .build();
+ consumer.consume(BuildFileType.INSTANCE, fileNameMatchers.toArray(new FileNameMatcher[0]));
}
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/AssignmentStatement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/AssignmentStatement.java
index fc0d2e1..b1e34eb 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/AssignmentStatement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/AssignmentStatement.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.lang.buildfile.psi;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
import com.intellij.util.PlatformIcons;
import javax.annotation.Nullable;
import javax.swing.Icon;
@@ -36,7 +37,8 @@
/** Returns the RHS of the assignment */
@Nullable
public Expression getAssignedValue() {
- return childToPsi(BuildElementTypes.EXPRESSIONS, 1);
+ PsiElement psi = childToPsi(BuildElementTypes.EXPRESSIONS, 1);
+ return psi instanceof Expression ? (Expression) psi : null;
}
@Override
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/AugmentedAssignmentStatement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/AugmentedAssignmentStatement.java
index 5d2384d..c3a3eb0 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/AugmentedAssignmentStatement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/AugmentedAssignmentStatement.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.lang.buildfile.psi;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
import javax.annotation.Nullable;
/** PSI element for an augmented assignment statement [expr += expr] */
@@ -28,13 +29,15 @@
/** Returns the LHS of the assignment */
@Nullable
public TargetExpression getLeftHandSideExpression() {
- return childToPsi(BuildElementTypes.EXPRESSIONS, 0);
+ PsiElement psi = childToPsi(BuildElementTypes.EXPRESSIONS, 0);
+ return psi instanceof TargetExpression ? (TargetExpression) psi : null;
}
/** Returns the RHS of the assignment */
@Nullable
public Expression getAssignedValue() {
- return childToPsi(BuildElementTypes.EXPRESSIONS, 1);
+ PsiElement psi = childToPsi(BuildElementTypes.EXPRESSIONS, 1);
+ return psi instanceof Expression ? (Expression) psi : null;
}
@Override
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BinaryOpExpression.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BinaryOpExpression.java
index 76a4387..3dab6d8 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BinaryOpExpression.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BinaryOpExpression.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.lang.buildfile.psi;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
import javax.annotation.Nullable;
/** PSI element for an binary operation expression [expr BIN_OP expr] */
@@ -33,12 +34,14 @@
/** Returns the LHS of the expression */
@Nullable
public Expression getLhs() {
- return childToPsi(BuildElementTypes.EXPRESSIONS, 0);
+ PsiElement psi = childToPsi(BuildElementTypes.EXPRESSIONS, 0);
+ return psi instanceof Expression ? (Expression) psi : null;
}
/** Returns the RHS of the expression */
@Nullable
public Expression getRhs() {
- return childToPsi(BuildElementTypes.EXPRESSIONS, 1);
+ PsiElement psi = childToPsi(BuildElementTypes.EXPRESSIONS, 1);
+ return psi instanceof Expression ? (Expression) psi : null;
}
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildElementImpl.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildElementImpl.java
index 55f472d..78990fb 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildElementImpl.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildElementImpl.java
@@ -82,13 +82,14 @@
return psiElements;
}
+ /** Finds the n'th child of the specified type */
@Nullable
- protected <T extends BuildElement> T childToPsi(TokenSet filterSet, int index) {
+ protected PsiElement childToPsi(TokenSet filterSet, int index) {
final ASTNode[] nodes = getNode().getChildren(filterSet);
if (nodes.length <= index) {
return null;
}
- return (T) nodes[index].getPsi();
+ return nodes[index].getPsi();
}
@Nullable
@@ -160,8 +161,8 @@
@Nullable
@Override
public WorkspacePath getWorkspacePath() {
- BuildFile file = (BuildFile) getContainingFile();
- return file.getWorkspacePath();
+ BuildFile file = getContainingFile();
+ return file != null ? file.getWorkspacePath() : null;
}
@Nullable
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/FuncallExpression.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/FuncallExpression.java
index e59d9a7..713807a 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/FuncallExpression.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/FuncallExpression.java
@@ -15,8 +15,6 @@
*/
package com.google.idea.blaze.base.lang.buildfile.psi;
-import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpec;
-import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpecProvider;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.google.idea.blaze.base.lang.buildfile.references.FuncallReference;
import com.google.idea.blaze.base.lang.buildfile.references.LabelUtils;
@@ -175,11 +173,6 @@
if (nameNode == null) {
return null;
}
- BuildLanguageSpec spec = BuildLanguageSpecProvider.getInstance().getLanguageSpec(getProject());
- if (spec != null && spec.hasRule(nameNode.getText())) {
- // don't try to follow references to built-in rules
- return null;
- }
TextRange range = PsiUtils.childRangeInParent(getTextRange(), nameNode.getTextRange());
return new FuncallReference(this, range);
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/FunctionStatement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/FunctionStatement.java
index 0dce2fe..3865d64 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/FunctionStatement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/FunctionStatement.java
@@ -19,8 +19,8 @@
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.util.PlatformIcons;
+import javax.annotation.Nullable;
import javax.swing.Icon;
-import org.jetbrains.annotations.Nullable;
/** PSI element for a function definition statement. */
public class FunctionStatement extends NamedBuildElement
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/Parameter.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/Parameter.java
index c873bb6..37298d2 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/Parameter.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/Parameter.java
@@ -19,8 +19,8 @@
import com.google.idea.blaze.base.lang.buildfile.lexer.TokenKind;
import com.intellij.icons.AllIcons;
import com.intellij.lang.ASTNode;
+import javax.annotation.Nullable;
import javax.swing.Icon;
-import org.jetbrains.annotations.Nullable;
/** PSI nodes for parameters in a function declaration */
public abstract class Parameter extends NamedBuildElement {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/ReferenceExpression.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/ReferenceExpression.java
index 287402c..755231e 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/ReferenceExpression.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/ReferenceExpression.java
@@ -20,7 +20,7 @@
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiReference;
import com.intellij.psi.tree.IElementType;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** References a PsiNamedElement */
public class ReferenceExpression extends BuildElementImpl implements Expression {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/ReturnStatement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/ReturnStatement.java
index a334c00..63926ee 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/ReturnStatement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/ReturnStatement.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.lang.buildfile.psi;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
import javax.annotation.Nullable;
/** A wrapper Statement class for return expressions. */
@@ -27,7 +28,8 @@
@Nullable
public Expression getReturnExpression() {
- return childToPsi(BuildElementTypes.EXPRESSIONS, 0);
+ PsiElement psi = childToPsi(BuildElementTypes.EXPRESSIONS, 0);
+ return psi instanceof Expression ? (Expression) psi : null;
}
@Override
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/TargetExpression.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/TargetExpression.java
index 405d0de..96a87ec 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/TargetExpression.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/TargetExpression.java
@@ -19,8 +19,8 @@
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiReference;
import com.intellij.util.PlatformIcons;
+import javax.annotation.Nullable;
import javax.swing.Icon;
-import org.jetbrains.annotations.Nullable;
/** References a PsiNamedElement */
public class TargetExpression extends NamedBuildElement implements Expression {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/quickfix/DeprecatedLoadQuickFix.java b/base/src/com/google/idea/blaze/base/lang/buildfile/quickfix/DeprecatedLoadQuickFix.java
new file mode 100644
index 0000000..c58a039
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/quickfix/DeprecatedLoadQuickFix.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2017 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.quickfix;
+
+import com.google.idea.blaze.base.bazel.BuildSystemProvider;
+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.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.intellij.codeInsight.intention.HighPriorityAction;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.history.core.Paths;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import java.io.File;
+import javax.annotation.Nullable;
+
+/** Offer to convert deprecated statements to label format. */
+public class DeprecatedLoadQuickFix implements LocalQuickFix, HighPriorityAction {
+
+ public static final DeprecatedLoadQuickFix INSTANCE = new DeprecatedLoadQuickFix();
+
+ @Override
+ public String getFamilyName() {
+ return "Fix load statement format";
+ }
+
+ @Override
+ public String getName() {
+ return getFamilyName();
+ }
+
+ @Override
+ public void applyFix(Project project, ProblemDescriptor descriptor) {
+ PsiElement element = descriptor.getPsiElement();
+ if (element instanceof StringLiteral) {
+ fixLoadString(project, (StringLiteral) element);
+ }
+ }
+
+ private static void fixLoadString(Project project, StringLiteral importString) {
+ String contents = importString.getStringContents();
+ if (!contents.startsWith("/") || contents.startsWith("//")) {
+ return;
+ }
+ WorkspaceRoot root = WorkspaceRoot.fromProjectSafe(project);
+ if (root == null) {
+ return;
+ }
+ WorkspacePath workspacePath = WorkspacePath.createIfValid(contents.substring(1));
+ if (workspacePath == null) {
+ return;
+ }
+ File file = root.fileForPath(workspacePath);
+ File parentPackageFile = findContainingPackage(project, file);
+ if (parentPackageFile == null) {
+ return;
+ }
+ WorkspacePath packagePath = root.workspacePathForSafe(parentPackageFile);
+ if (packagePath == null) {
+ return;
+ }
+ String relativePath =
+ Paths.relativeIfUnder(workspacePath.relativePath(), packagePath.relativePath());
+ if (relativePath == null) {
+ return;
+ }
+ String newString = "//" + packagePath + ":" + relativePath;
+
+ ASTNode node = importString.getNode();
+ node.replaceChild(
+ node.getFirstChildNode(), PsiUtils.createNewLabel(importString.getProject(), newString));
+ }
+
+ @Nullable
+ private static File findContainingPackage(Project project, File file) {
+ BuildSystemProvider provider = Blaze.getBuildSystemProvider(project);
+ file = file.getParentFile();
+ while (file != null) {
+ File buildFile = provider.findBuildFileInDirectory(file);
+ if (buildFile != null) {
+ return file;
+ }
+ file = file.getParentFile();
+ }
+ return null;
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/FileLookupData.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/FileLookupData.java
index eabe428..8a21adb 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/FileLookupData.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/FileLookupData.java
@@ -32,8 +32,8 @@
import com.intellij.util.PathUtil;
import com.intellij.util.PlatformIcons;
import icons.BlazeIcons;
+import javax.annotation.Nullable;
import javax.swing.Icon;
-import org.jetbrains.annotations.Nullable;
/** The data relevant to finding file lookups. */
public class FileLookupData {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/FuncallReference.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/FuncallReference.java
index 526e2ec..b3d69dd 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/FuncallReference.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/FuncallReference.java
@@ -31,7 +31,7 @@
public class FuncallReference extends PsiReferenceBase<FuncallExpression> {
public FuncallReference(FuncallExpression element, TextRange rangeInElement) {
- super(element, rangeInElement, /*soft*/ true);
+ super(element, rangeInElement, /* soft */ true);
}
@Nullable
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/LabelReference.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/LabelReference.java
index f1e6542..9bbf574 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/LabelReference.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/LabelReference.java
@@ -35,8 +35,8 @@
import com.intellij.psi.PsiReferenceBase;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Converts a blaze label into an absolute path, then resolves that path to a PsiElements */
public class LabelReference extends PsiReferenceBase<StringLiteral> {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/LoadedSymbolReference.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/LoadedSymbolReference.java
index 219d843..44fa77f 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/LoadedSymbolReference.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/LoadedSymbolReference.java
@@ -33,7 +33,7 @@
private final LabelReference bzlFileReference;
public LoadedSymbolReference(StringLiteral element, LabelReference bzlFileReference) {
- super(element, new TextRange(0, element.getTextLength()), /*soft*/ false);
+ super(element, new TextRange(0, element.getTextLength()), /* soft */ false);
this.bzlFileReference = bzlFileReference;
}
@@ -54,7 +54,7 @@
return EMPTY_ARRAY;
}
CompletionResultsProcessor processor =
- new CompletionResultsProcessor(myElement, myElement.getQuoteType());
+ new CompletionResultsProcessor(myElement, myElement.getQuoteType(), false);
((BuildFile) bzlFile).searchSymbolsInScope(processor, null);
return processor.getResults().toArray();
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/LocalReference.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/LocalReference.java
index 85808b1..08b3237 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/LocalReference.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/LocalReference.java
@@ -33,7 +33,7 @@
public class LocalReference extends PsiReferenceBase<ReferenceExpression> {
public LocalReference(ReferenceExpression element) {
- super(element, new TextRange(0, element.getTextLength()), /*soft*/ false);
+ super(element, new TextRange(0, element.getTextLength()), /* soft */ false);
}
@Nullable
@@ -49,7 +49,7 @@
@Override
public Object[] getVariants() {
CompletionResultsProcessor processor =
- new CompletionResultsProcessor(myElement, QuoteType.NoQuotes);
+ new CompletionResultsProcessor(myElement, QuoteType.NoQuotes, true);
ResolveUtil.searchInScope(myElement, processor);
return processor.getResults().toArray();
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/TargetReference.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/TargetReference.java
index 52ee6da..68ba606 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/TargetReference.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/TargetReference.java
@@ -34,7 +34,7 @@
public class TargetReference extends PsiReferenceBase<TargetExpression> {
public TargetReference(TargetExpression element) {
- super(element, new TextRange(0, element.getTextLength()), /*soft*/ true);
+ super(element, new TextRange(0, element.getTextLength()), /* soft */ true);
}
@Nullable
@@ -51,7 +51,7 @@
@Override
public Object[] getVariants() {
CompletionResultsProcessor processor =
- new CompletionResultsProcessor(myElement, QuoteType.NoQuotes);
+ new CompletionResultsProcessor(myElement, QuoteType.NoQuotes, true);
ResolveUtil.searchInScope(myElement, processor);
return processor.getResults().toArray();
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/search/BlazePackage.java b/base/src/com/google/idea/blaze/base/lang/buildfile/search/BlazePackage.java
index 6f1b102..51cf7a7 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/search/BlazePackage.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/search/BlazePackage.java
@@ -15,10 +15,12 @@
*/
package com.google.idea.blaze.base.lang.buildfile.search;
+import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.history.core.Paths;
+import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PackagePrefixFileSystemItem;
import com.intellij.psi.PsiDirectory;
@@ -192,4 +194,27 @@
"%s package: %s",
Blaze.buildSystemName(buildFile.getProject()), buildFile.getPackageWorkspacePath());
}
+
+ public static boolean hasBlazePackageChild(PsiDirectory directory) {
+ ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(directory.getProject());
+ BuildSystemProvider buildSystemProvider = Blaze.getBuildSystemProvider(directory.getProject());
+ return hasBlazePackageChild(index, buildSystemProvider, directory);
+ }
+
+ private static boolean hasBlazePackageChild(
+ ProjectFileIndex index, BuildSystemProvider buildSystemProvider, PsiDirectory directory) {
+ if (!index.isInSourceContent(directory.getVirtualFile())) {
+ // only search project files
+ return false;
+ }
+ if (buildSystemProvider.findBuildFileInDirectory(directory.getVirtualFile()) != null) {
+ return true;
+ }
+ for (PsiDirectory child : directory.getSubdirectories()) {
+ if (hasBlazePackageChild(index, buildSystemProvider, child)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/search/BuildLabelReferenceSearcher.java b/base/src/com/google/idea/blaze/base/lang/buildfile/search/BuildReferenceSearcher.java
similarity index 93%
rename from base/src/com/google/idea/blaze/base/lang/buildfile/search/BuildLabelReferenceSearcher.java
rename to base/src/com/google/idea/blaze/base/lang/buildfile/search/BuildReferenceSearcher.java
index 688cc95..44af324 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/search/BuildLabelReferenceSearcher.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/search/BuildReferenceSearcher.java
@@ -20,7 +20,7 @@
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile.BlazeFileType;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
-import com.google.idea.blaze.base.lang.buildfile.psi.FunctionStatement;
+import com.google.idea.blaze.base.lang.buildfile.psi.NamedBuildElement;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.google.idea.blaze.base.lang.buildfile.references.LabelUtils;
import com.google.idea.blaze.base.model.primitives.Label;
@@ -39,23 +39,24 @@
import java.util.List;
import javax.annotation.Nullable;
-/** String search for label references in BUILD files */
-public class BuildLabelReferenceSearcher extends QueryExecutorBase<PsiReference, SearchParameters> {
+/** String search for references in BUILD files */
+public class BuildReferenceSearcher extends QueryExecutorBase<PsiReference, SearchParameters> {
- public BuildLabelReferenceSearcher() {
+ public BuildReferenceSearcher() {
super(true);
}
@Override
public void processQuery(SearchParameters params, Processor<PsiReference> consumer) {
PsiElement element = params.getElementToSearch();
- if (element instanceof FunctionStatement) {
- String fnName = ((FunctionStatement) element).getName();
+ if (element instanceof NamedBuildElement) {
+ String fnName = ((NamedBuildElement) element).getName();
if (fnName != null) {
searchForString(params, element, fnName);
}
return;
}
+
PsiFile file = ResolveUtil.asFileSearch(element);
if (file != null) {
processFileReferences(params, file);
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/stubs/BuildFileStubBuilder.java b/base/src/com/google/idea/blaze/base/lang/buildfile/stubs/BuildFileStubBuilder.java
index 73d1e58..4c4a53a 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/stubs/BuildFileStubBuilder.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/stubs/BuildFileStubBuilder.java
@@ -19,7 +19,7 @@
import com.intellij.psi.stubs.BinaryFileStubBuilder;
import com.intellij.psi.stubs.Stub;
import com.intellij.util.indexing.FileContent;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Empty stub builder to suppress errors when IntelliJ is looking for stubs. */
public class BuildFileStubBuilder implements BinaryFileStubBuilder {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/sync/BuildLangSyncPlugin.java b/base/src/com/google/idea/blaze/base/lang/buildfile/sync/BuildLangSyncPlugin.java
index 0279a2f..c901eb8 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/sync/BuildLangSyncPlugin.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/sync/BuildLangSyncPlugin.java
@@ -15,8 +15,8 @@
*/
package com.google.idea.blaze.base.lang.buildfile.sync;
-import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.ideinfo.TargetMap;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpec;
@@ -62,7 +62,7 @@
@Nullable SyncState previousSyncState) {
LanguageSpecResult spec =
- getBuildLanguageSpec(project, workspaceRoot, previousSyncState, context);
+ getBuildLanguageSpec(project, workspaceRoot, projectViewSet, previousSyncState, context);
if (spec != null) {
syncStateBuilder.put(LanguageSpecResult.class, spec);
}
@@ -72,6 +72,7 @@
private static LanguageSpecResult getBuildLanguageSpec(
Project project,
WorkspaceRoot workspace,
+ ProjectViewSet projectViewSet,
@Nullable SyncState previousSyncState,
BlazeContext parentContext) {
LanguageSpecResult oldResult =
@@ -84,7 +85,8 @@
parentContext,
(context) -> {
context.push(new TimingScope("BUILD language spec"));
- BuildLanguageSpec spec = parseLanguageSpec(project, workspace, context);
+ BuildLanguageSpec spec =
+ parseLanguageSpec(project, workspace, projectViewSet, context);
if (spec != null) {
return new LanguageSpecResult(spec, System.currentTimeMillis());
}
@@ -95,7 +97,10 @@
@Nullable
private static BuildLanguageSpec parseLanguageSpec(
- Project project, WorkspaceRoot workspace, BlazeContext context) {
+ Project project,
+ WorkspaceRoot workspace,
+ ProjectViewSet projectViewSet,
+ BlazeContext context) {
try {
// it's wasteful converting to a string and back, but uses existing code,
// and has a very minor cost (this is only run once per workspace)
@@ -103,9 +108,9 @@
BlazeInfo.getInstance()
.runBlazeInfoGetBytes(
context,
- Blaze.getBuildSystem(project),
+ Blaze.getBuildSystemProvider(project).getSyncBinaryPath(),
workspace,
- ImmutableList.of(),
+ BlazeFlags.buildFlags(project, projectViewSet),
BlazeInfo.BUILD_LANGUAGE);
return BuildLanguageSpec.fromProto(Build.BuildLanguage.parseFrom(future.get()));
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildAnnotator.java b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildAnnotator.java
index 84028f8..b4b9230 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildAnnotator.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildAnnotator.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.lang.buildfile.validation;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildElementVisitor;
+import com.intellij.lang.annotation.Annotation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.psi.PsiElement;
@@ -39,7 +40,11 @@
}
}
- protected void markError(PsiElement element, String message) {
- getHolder().createErrorAnnotation(element, message);
+ protected Annotation markError(PsiElement element, String message) {
+ return getHolder().createErrorAnnotation(element, message);
+ }
+
+ protected Annotation markWarning(PsiElement element, String message) {
+ return getHolder().createWarningAnnotation(element, message);
}
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/LoadErrorAnnotator.java b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/LoadErrorAnnotator.java
deleted file mode 100644
index c8ea27a..0000000
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/LoadErrorAnnotator.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.validation;
-
-import com.google.idea.blaze.base.lang.buildfile.psi.Argument;
-import com.google.idea.blaze.base.lang.buildfile.psi.BuildElement;
-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.FunctionStatement;
-import com.google.idea.blaze.base.lang.buildfile.psi.LoadStatement;
-import com.google.idea.blaze.base.lang.buildfile.psi.LoadedSymbol;
-import com.google.idea.blaze.base.lang.buildfile.psi.ParameterList;
-import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
-import com.google.idea.blaze.base.lang.buildfile.references.LabelReference;
-import com.intellij.psi.PsiElement;
-import java.util.Arrays;
-import javax.annotation.Nullable;
-
-/**
- * Error annotations for load statements, post parsing.
- *
- * <p>This has been turned off because it's unusable. BuildFile is re-parsed *every* time it's
- * touched, and is never cached. Until this is fixed, we can't run any annotators touching the file.
- *
- * <p>One option: try moving all expensive checks to 'visitFile', so they're not run in parallel
- */
-public class LoadErrorAnnotator extends BuildAnnotator {
-
- @Override
- public void visitLoadStatement(LoadStatement node) {
- BuildElement[] children = node.buildElementChildren();
- // StringLiteral[] strings = node..getChildStrings();
- if (children.length == 0) {
- return;
- }
- PsiElement skylarkRef = getSkylarkRef(children[0]);
- if (skylarkRef == null) {
- markError(children[0], "Cannot find this Skylark module");
- return;
- }
- if (!(skylarkRef instanceof BuildFile)) {
- markError(children[0], children[0].getText() + " is not a Skylark module");
- return;
- }
-
- LoadedSymbol[] symbols =
- Arrays.stream(children)
- .filter(element -> element instanceof LoadedSymbol)
- .toArray(LoadedSymbol[]::new);
- if (symbols.length == 1) {
- markError(node, "No symbols imported from Skylark module");
- return;
- }
- BuildFile skylarkModule = (BuildFile) skylarkRef;
- for (int i = 0; i < symbols.length; i++) {
- String text = symbols[i].getSymbolString();
- if (text == null) {
- continue;
- }
- FunctionStatement fn = skylarkModule.findDeclaredFunction(text);
- if (fn == null) {
- markError(
- symbols[i],
- "Function '" + text + "' not found in Skylark module " + skylarkModule.getFileName());
- }
- }
- }
-
- @Nullable
- private static PsiElement getSkylarkRef(BuildElement firstChild) {
- if (firstChild instanceof StringLiteral) {
- return new LabelReference((StringLiteral) firstChild, false).resolve();
- }
- return null;
- }
-
- @Override
- public void visitFuncallExpression(FuncallExpression node) {
- FunctionStatement function = (FunctionStatement) node.getReferencedElement();
- if (function == null) {
- // likely a built-in rule.
- return;
- }
- // check keyword args match function parameters
- ParameterList params = function.getParameterList();
- if (params == null || params.hasStarStar()) {
- return;
- }
- for (Argument arg : node.getArguments()) {
- if (arg instanceof Argument.Keyword) {
- String name = arg.getName();
- if (name != null && params.findParameterByName(name) == null) {
- markError(
- arg,
- "No parameter found in '" + node.getFunctionName() + "' with name '" + name + "'");
- }
- }
- }
- }
-}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/LoadStatementAnnotator.java b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/LoadStatementAnnotator.java
new file mode 100644
index 0000000..b3c8a55
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/LoadStatementAnnotator.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017 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.validation;
+
+import com.google.idea.blaze.base.lang.buildfile.psi.LoadStatement;
+import com.google.idea.blaze.base.lang.buildfile.psi.LoadedSymbol;
+import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
+import com.google.idea.blaze.base.lang.buildfile.quickfix.DeprecatedLoadQuickFix;
+import com.intellij.codeInspection.InspectionManager;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.ProblemHighlightType;
+import com.intellij.lang.annotation.Annotation;
+import javax.annotation.Nullable;
+
+/** Adds warning/error annotations to load statements. */
+public class LoadStatementAnnotator extends BuildAnnotator {
+
+ @Override
+ public void visitLoadStatement(LoadStatement node) {
+ validateImportTarget(node.getImportPsiElement());
+ }
+
+ @Override
+ public void visitLoadedSymbol(LoadedSymbol node) {
+ StringLiteral loadedString = node.getImport();
+ if (loadedString == null) {
+ return;
+ }
+ String name = loadedString.getStringContents();
+ if (name.startsWith("_")) {
+ markError(node, String.format("Symbol '%s' is private and cannot be imported.", name));
+ }
+ }
+
+ private void validateImportTarget(@Nullable StringLiteral target) {
+ if (target == null) {
+ return;
+ }
+ String targetString = target.getStringContents();
+ if (targetString == null
+ || targetString.startsWith(":")
+ || targetString.startsWith("//")
+ || targetString.length() < 2) {
+ return;
+ }
+ if (targetString.startsWith("/")) {
+ Annotation annotation =
+ markWarning(
+ target, "Deprecated load syntax; loaded Skylark module should by in label format.");
+ InspectionManager inspectionManager = InspectionManager.getInstance(target.getProject());
+ ProblemDescriptor descriptor =
+ inspectionManager.createProblemDescriptor(
+ target,
+ annotation.getMessage(),
+ DeprecatedLoadQuickFix.INSTANCE,
+ ProblemHighlightType.LIKE_DEPRECATED,
+ true);
+ annotation.registerFix(DeprecatedLoadQuickFix.INSTANCE, null, null, descriptor);
+ return;
+ }
+ markError(target, "Invalid load syntax: missing Skylark module.");
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/views/BuildStructureViewElement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/views/BuildStructureViewElement.java
index 75768dd..7ae6217 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/views/BuildStructureViewElement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/views/BuildStructureViewElement.java
@@ -21,8 +21,8 @@
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
import java.util.Collection;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Handles nodes in Structure View. */
public class BuildStructureViewElement extends PsiTreeElementBase<BuildElement> {
diff --git a/base/src/com/google/idea/blaze/base/lang/projectview/completion/ProjectViewKeywordCompletionContributor.java b/base/src/com/google/idea/blaze/base/lang/projectview/completion/ProjectViewKeywordCompletionContributor.java
index 88d8d2b..6020f31 100644
--- a/base/src/com/google/idea/blaze/base/lang/projectview/completion/ProjectViewKeywordCompletionContributor.java
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/completion/ProjectViewKeywordCompletionContributor.java
@@ -43,7 +43,7 @@
import com.intellij.psi.PsiFile;
import com.intellij.util.ProcessingContext;
import java.util.List;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Completes project view section names. */
public class ProjectViewKeywordCompletionContributor extends CompletionContributor {
diff --git a/base/src/com/google/idea/blaze/base/lang/projectview/formatting/ProjectViewCommenter.java b/base/src/com/google/idea/blaze/base/lang/projectview/formatting/ProjectViewCommenter.java
index 09aaa68..33667ee 100644
--- a/base/src/com/google/idea/blaze/base/lang/projectview/formatting/ProjectViewCommenter.java
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/formatting/ProjectViewCommenter.java
@@ -19,7 +19,7 @@
import com.intellij.lang.CodeDocumentationAwareCommenter;
import com.intellij.psi.PsiComment;
import com.intellij.psi.tree.IElementType;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Supports (un)commenting lines via IntelliJ */
public class ProjectViewCommenter implements CodeDocumentationAwareCommenter {
diff --git a/base/src/com/google/idea/blaze/base/model/primitives/ExecutionRootPath.java b/base/src/com/google/idea/blaze/base/model/primitives/ExecutionRootPath.java
index 4c8d3f0..5e060b7 100644
--- a/base/src/com/google/idea/blaze/base/model/primitives/ExecutionRootPath.java
+++ b/base/src/com/google/idea/blaze/base/model/primitives/ExecutionRootPath.java
@@ -87,7 +87,7 @@
if (root.isAbsolute() != path.isAbsolute()) {
return null;
}
- if (!isAncestor(root.getPath(), path.getPath(), false /* strict */)) {
+ if (!isAncestor(root.getPath(), path.getPath(), /* strict */ false)) {
return null;
}
String relativePath = FileUtil.getRelativePath(root, path);
diff --git a/base/src/com/google/idea/blaze/base/model/primitives/WorkspacePath.java b/base/src/com/google/idea/blaze/base/model/primitives/WorkspacePath.java
index 00ce9ee..b3cbbf0 100644
--- a/base/src/com/google/idea/blaze/base/model/primitives/WorkspacePath.java
+++ b/base/src/com/google/idea/blaze/base/model/primitives/WorkspacePath.java
@@ -18,9 +18,9 @@
import com.google.idea.blaze.base.ui.BlazeValidationError;
import java.io.Serializable;
import java.util.Collection;
+import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* Represents a path relative to the workspace root. The path component separator is Blaze specific.
diff --git a/base/src/com/google/idea/blaze/base/projectview/ProjectViewManagerImpl.java b/base/src/com/google/idea/blaze/base/projectview/ProjectViewManagerImpl.java
index bab57dc..1635b84 100644
--- a/base/src/com/google/idea/blaze/base/projectview/ProjectViewManagerImpl.java
+++ b/base/src/com/google/idea/blaze/base/projectview/ProjectViewManagerImpl.java
@@ -28,8 +28,8 @@
import java.io.File;
import java.io.IOException;
import java.util.List;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Project view manager implementation. */
/** Stores mutable per-project user settings. */
diff --git a/base/src/com/google/idea/blaze/base/projectview/ProjectViewStorageManagerImpl.java b/base/src/com/google/idea/blaze/base/projectview/ProjectViewStorageManagerImpl.java
index 729b1d8..49a5d3b 100644
--- a/base/src/com/google/idea/blaze/base/projectview/ProjectViewStorageManagerImpl.java
+++ b/base/src/com/google/idea/blaze/base/projectview/ProjectViewStorageManagerImpl.java
@@ -17,18 +17,16 @@
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vfs.LocalFileSystem;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Project view storage implementation. */
final class ProjectViewStorageManagerImpl extends ProjectViewStorageManager {
- private static final Logger logger = Logger.getInstance(ProjectViewManagerImpl.class);
@Nullable
@Override
diff --git a/base/src/com/google/idea/blaze/base/projectview/parser/ParseContext.java b/base/src/com/google/idea/blaze/base/projectview/parser/ParseContext.java
index a7b626a..29bacb8 100644
--- a/base/src/com/google/idea/blaze/base/projectview/parser/ParseContext.java
+++ b/base/src/com/google/idea/blaze/base/projectview/parser/ParseContext.java
@@ -22,7 +22,7 @@
import com.google.idea.blaze.base.ui.BlazeValidationError;
import java.io.File;
import java.util.List;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Context for the project view parser. */
public class ParseContext {
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/ImportSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/ImportSection.java
index e377b09..4d9b6ef 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/ImportSection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/ImportSection.java
@@ -26,7 +26,7 @@
import com.google.idea.blaze.base.ui.BlazeValidationError;
import java.io.File;
import java.util.List;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** "import" section. */
public class ImportSection {
diff --git a/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfiguration.java b/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfiguration.java
index 9448702..7f59707 100644
--- a/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfiguration.java
+++ b/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfiguration.java
@@ -15,13 +15,18 @@
*/
package com.google.idea.blaze.base.run;
+import static java.util.stream.Collectors.toList;
+
import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.projectview.ProjectViewManager;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerProvider;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
@@ -29,7 +34,10 @@
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.google.idea.blaze.base.run.targetfinder.TargetFinder;
import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.settings.BlazeImportSettings;
+import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.base.sync.projectview.ImportRoots;
import com.google.idea.blaze.base.ui.UiUtil;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
@@ -55,7 +63,6 @@
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ui.UIUtil;
import java.util.Collection;
-import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
@@ -496,17 +503,27 @@
}
private static Collection<String> getTargets(Project project) {
- List<String> result = Lists.newArrayList();
BlazeProjectData projectData =
BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
- if (projectData != null) {
- for (TargetIdeInfo target : projectData.targetMap.targets()) {
- if (target.isPlainTarget()) {
- result.add(target.key.label.toString());
- }
- }
+ BlazeImportSettings importSettings =
+ BlazeImportSettingsManager.getInstance(project).getImportSettings();
+ ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
+ if (projectData == null || importSettings == null || projectViewSet == null) {
+ return ImmutableList.of();
}
- return result;
+ ImportRoots importRoots =
+ ImportRoots.builder(
+ WorkspaceRoot.fromImportSettings(importSettings), importSettings.getBuildSystem())
+ .add(projectViewSet)
+ .build();
+ return projectData
+ .targetMap
+ .targets()
+ .stream()
+ .filter(TargetIdeInfo::isPlainTarget)
+ .filter(target -> importRoots.importAsSource(target.key.label))
+ .map(target -> target.key.label.toString())
+ .collect(toList());
}
}
}
diff --git a/base/src/com/google/idea/blaze/base/run/BlazeRunConfiguration.java b/base/src/com/google/idea/blaze/base/run/BlazeRunConfiguration.java
index 5a4daed..3b98ced 100644
--- a/base/src/com/google/idea/blaze/base/run/BlazeRunConfiguration.java
+++ b/base/src/com/google/idea/blaze/base/run/BlazeRunConfiguration.java
@@ -16,7 +16,7 @@
package com.google.idea.blaze.base.run;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Marker interface for all run configurations */
public interface BlazeRunConfiguration {
diff --git a/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationSyncListener.java b/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationSyncListener.java
index a1e0549..dfcc68a 100644
--- a/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationSyncListener.java
+++ b/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationSyncListener.java
@@ -119,7 +119,7 @@
if (configurationFactory.handlesTarget(project, blazeProjectData, label)) {
final RunnerAndConfigurationSettings settings =
configurationFactory.createForTarget(project, runManager, label);
- runManager.addConfiguration(settings, false /* isShared */);
+ runManager.addConfiguration(settings, /* isShared */ false);
if (runManager.getSelectedConfiguration() == null) {
// TODO(joshgiles): Better strategy for picking initially selected config.
runManager.setSelectedConfiguration(settings);
diff --git a/base/src/com/google/idea/blaze/base/run/TargetNameHeuristic.java b/base/src/com/google/idea/blaze/base/run/TargetNameHeuristic.java
index c2cf40a..507fe2c 100644
--- a/base/src/com/google/idea/blaze/base/run/TargetNameHeuristic.java
+++ b/base/src/com/google/idea/blaze/base/run/TargetNameHeuristic.java
@@ -17,6 +17,7 @@
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.ideinfo.TestIdeInfo.TestSize;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import java.io.File;
import javax.annotation.Nullable;
@@ -25,7 +26,8 @@
public class TargetNameHeuristic implements TestTargetHeuristic {
@Override
- public boolean matchesSource(TargetIdeInfo target, File sourceFile, @Nullable TestSize testSize) {
+ public boolean matchesSource(
+ Project project, TargetIdeInfo target, File sourceFile, @Nullable TestSize testSize) {
String filePathWithoutExtension = FileUtil.getNameWithoutExtension(sourceFile.getPath());
String targetName = target.key.label.targetName().toString();
if (!filePathWithoutExtension.endsWith(targetName)) {
diff --git a/base/src/com/google/idea/blaze/base/run/TestSizeHeuristic.java b/base/src/com/google/idea/blaze/base/run/TestSizeHeuristic.java
index 67f899a..5b40bcf 100644
--- a/base/src/com/google/idea/blaze/base/run/TestSizeHeuristic.java
+++ b/base/src/com/google/idea/blaze/base/run/TestSizeHeuristic.java
@@ -18,6 +18,7 @@
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.ideinfo.TestIdeInfo;
import com.google.idea.blaze.base.ideinfo.TestIdeInfo.TestSize;
+import com.intellij.openapi.project.Project;
import java.io.File;
import javax.annotation.Nullable;
@@ -25,7 +26,8 @@
public class TestSizeHeuristic implements TestTargetHeuristic {
@Override
- public boolean matchesSource(TargetIdeInfo target, File sourceFile, @Nullable TestSize testSize) {
+ public boolean matchesSource(
+ Project project, TargetIdeInfo target, File sourceFile, @Nullable TestSize testSize) {
// If testSize == null then prefer small
// Some test runners will assume no size annotation == small and filter on that, others will not
TestSize size = testSize != null ? testSize : TestIdeInfo.DEFAULT_NON_ANNOTATED_TEST_SIZE;
diff --git a/base/src/com/google/idea/blaze/base/run/TestTargetHeuristic.java b/base/src/com/google/idea/blaze/base/run/TestTargetHeuristic.java
index 9f31b39..7d5576a 100644
--- a/base/src/com/google/idea/blaze/base/run/TestTargetHeuristic.java
+++ b/base/src/com/google/idea/blaze/base/run/TestTargetHeuristic.java
@@ -16,9 +16,10 @@
package com.google.idea.blaze.base.run;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
-import com.google.idea.blaze.base.ideinfo.TestIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TestIdeInfo.TestSize;
import com.google.idea.blaze.base.model.primitives.Label;
import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -44,7 +45,7 @@
}
Collection<TargetIdeInfo> rules =
TestTargetFinder.getInstance(element.getProject()).testTargetsForSourceFile(file);
- return chooseTestTargetForSourceFile(file, rules, null);
+ return chooseTestTargetForSourceFile(element.getProject(), file, rules, null);
}
static File getContainingFile(PsiElement element) {
@@ -62,13 +63,16 @@
*/
@Nullable
static Label chooseTestTargetForSourceFile(
- File sourceFile, Collection<TargetIdeInfo> targets, @Nullable TestIdeInfo.TestSize testSize) {
+ Project project,
+ File sourceFile,
+ Collection<TargetIdeInfo> targets,
+ @Nullable TestSize testSize) {
for (TestTargetHeuristic filter : EP_NAME.getExtensions()) {
TargetIdeInfo match =
targets
.stream()
- .filter(target -> filter.matchesSource(target, sourceFile, testSize))
+ .filter(target -> filter.matchesSource(project, target, sourceFile, testSize))
.findFirst()
.orElse(null);
@@ -81,5 +85,5 @@
/** Returns true if the rule and source file match, according to this heuristic. */
boolean matchesSource(
- TargetIdeInfo target, File sourceFile, @Nullable TestIdeInfo.TestSize testSize);
+ Project project, TargetIdeInfo target, File sourceFile, @Nullable TestSize testSize);
}
diff --git a/base/src/com/google/idea/blaze/base/run/TestTargetSourcesHeuristic.java b/base/src/com/google/idea/blaze/base/run/TestTargetSourcesHeuristic.java
new file mode 100644
index 0000000..f42cf1b
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/TestTargetSourcesHeuristic.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2017 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.run;
+
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TestIdeInfo.TestSize;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
+import com.intellij.openapi.project.Project;
+import java.io.File;
+import javax.annotation.Nullable;
+
+/**
+ * Matches source files to test targets, if the source file is present in the test target's 'srcs'
+ * list. Only looks for exact matches.
+ */
+public class TestTargetSourcesHeuristic implements TestTargetHeuristic {
+
+ @Override
+ public boolean matchesSource(
+ Project project, TargetIdeInfo target, File sourceFile, @Nullable TestSize testSize) {
+ BlazeProjectData projectData =
+ BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
+ if (projectData == null) {
+ return false;
+ }
+ ArtifactLocationDecoder decoder = projectData.artifactLocationDecoder;
+ for (ArtifactLocation src : target.sources) {
+ if (decoder.decode(src).equals(sourceFile)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationRunner.java b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationRunner.java
index 7c508e2..2c6bd90 100644
--- a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationRunner.java
+++ b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationRunner.java
@@ -38,7 +38,6 @@
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
-import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
@@ -65,9 +64,6 @@
public final class BlazeCommandGenericRunConfigurationRunner
implements BlazeCommandRunConfigurationRunner {
- private static final BoolExperiment smRunnerUiEnabled =
- new BoolExperiment("use.smrunner.ui.general", true);
-
@Override
public RunProfileState getRunProfileState(Executor executor, ExecutionEnvironment environment) {
return new BlazeCommandRunProfileState(environment, ImmutableList.of());
@@ -152,9 +148,7 @@
new ScopedBlazeProcessHandler.ScopedProcessHandlerDelegate() {
@Override
public void onBlazeContextStart(BlazeContext context) {
- context
- .push(new IssuesScope(project))
- .push(new IdeaLogScope());
+ context.push(new IssuesScope(project)).push(new IdeaLogScope());
}
@Override
@@ -171,28 +165,27 @@
ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
assert projectViewSet != null;
+ String binaryPath =
+ handlerState.getBlazeBinary() != null
+ ? handlerState.getBlazeBinary()
+ : Blaze.getBuildSystemProvider(project).getBinaryPath();
+
BlazeCommand.Builder command =
- BlazeCommand.builder(Blaze.getBuildSystem(project), handlerState.getCommand())
- .setBlazeBinary(handlerState.getBlazeBinary())
+ BlazeCommand.builder(binaryPath, handlerState.getCommand())
.addTargets(configuration.getTarget())
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
.addBlazeFlags(testHandlerFlags)
.addBlazeFlags(handlerState.getBlazeFlags())
.addExeFlags(handlerState.getExeFlags());
- boolean runDistributed = handlerState.getRunOnDistributedExecutor();
command.addBlazeFlags(
DistributedExecutorSupport.getBlazeFlags(
project, handlerState.getRunOnDistributedExecutor()));
- if (!runDistributed) {
- command.addBlazeFlags(BlazeFlags.TEST_OUTPUT_STREAMED);
- }
return command.build();
}
private boolean canUseTestUi() {
- return smRunnerUiEnabled.getValue()
- && BlazeCommandName.TEST.equals(handlerState.getCommand())
+ return BlazeCommandName.TEST.equals(handlerState.getCommand())
&& !handlerState.getRunOnDistributedExecutor();
}
}
diff --git a/base/src/com/google/idea/blaze/base/run/filter/BlazeTargetFilter.java b/base/src/com/google/idea/blaze/base/run/filter/BlazeTargetFilter.java
index 1cf0e0c..07e6233 100644
--- a/base/src/com/google/idea/blaze/base/run/filter/BlazeTargetFilter.java
+++ b/base/src/com/google/idea/blaze/base/run/filter/BlazeTargetFilter.java
@@ -25,7 +25,7 @@
import com.intellij.psi.PsiElement;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Parse blaze targets in streamed output. */
public class BlazeTargetFilter implements Filter {
diff --git a/base/src/com/google/idea/blaze/base/run/producers/AllInPackageBlazeConfigurationProducer.java b/base/src/com/google/idea/blaze/base/run/producers/AllInPackageBlazeConfigurationProducer.java
index 154a9be..372a315 100644
--- a/base/src/com/google/idea/blaze/base/run/producers/AllInPackageBlazeConfigurationProducer.java
+++ b/base/src/com/google/idea/blaze/base/run/producers/AllInPackageBlazeConfigurationProducer.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.run.producers;
import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.lang.buildfile.search.BlazePackage;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
@@ -93,13 +94,11 @@
private static PsiDirectory getTestDirectory(ConfigurationContext context) {
WorkspaceRoot root = WorkspaceRoot.fromProject(context.getModule().getProject());
PsiElement location = context.getPsiLocation();
- if (location instanceof PsiDirectory) {
- PsiDirectory dir = (PsiDirectory) location;
- if (isInWorkspace(root, dir)) {
- return dir;
- }
+ if (!(location instanceof PsiDirectory)) {
+ return null;
}
- return null;
+ PsiDirectory dir = (PsiDirectory) location;
+ return isInWorkspace(root, dir) && BlazePackage.hasBlazePackageChild(dir) ? dir : null;
}
@Nullable
diff --git a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeCompositeTestEventsHandler.java b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeCompositeTestEventsHandler.java
index 5d86bdf..21bf76a 100644
--- a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeCompositeTestEventsHandler.java
+++ b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeCompositeTestEventsHandler.java
@@ -20,6 +20,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.idea.blaze.base.model.primitives.Kind;
+import com.google.idea.blaze.base.run.smrunner.BlazeXmlSchema.TestSuite;
import com.intellij.execution.Location;
import com.intellij.execution.testframework.actions.AbstractRerunFailedTestsAction;
import com.intellij.execution.testframework.sm.runner.SMTestLocator;
@@ -95,6 +96,12 @@
return null;
}
+ @Override
+ public boolean ignoreSuite(@Nullable Kind kind, TestSuite suite) {
+ BlazeTestEventsHandler handler = kind != null ? getHandlers().get(kind) : null;
+ return handler != null ? handler.ignoreSuite(kind, suite) : super.ignoreSuite(kind, suite);
+ }
+
/** Converts the testsuite name in the blaze test XML to a user-friendly format */
@Override
public String suiteDisplayName(@Nullable Kind kind, String rawName) {
diff --git a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeTestEventsHandler.java b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeTestEventsHandler.java
index 2f3286f..7bb4325 100644
--- a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeTestEventsHandler.java
+++ b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeTestEventsHandler.java
@@ -44,18 +44,17 @@
/**
* Blaze/Bazel flags required for test UI.<br>
- * Forces local test execution, without sharding.
+ * Forces local test execution, without retries.
*/
public static ImmutableList<String> getBlazeFlags(Project project) {
ImmutableList.Builder<String> flags =
- ImmutableList.<String>builder()
- .add(
- "--test_sharding_strategy=disabled",
- "--runs_per_test=1",
- "--flaky_test_attempts=1");
+ ImmutableList.<String>builder().add("--runs_per_test=1", "--flaky_test_attempts=1");
if (Blaze.getBuildSystem(project) == BuildSystem.Blaze) {
flags.add("--test_strategy=local");
}
+ if (Blaze.getBuildSystem(project) == BuildSystem.Bazel) {
+ flags.add("--test_sharding_strategy=disabled");
+ }
return flags.build();
}
@@ -125,8 +124,8 @@
}
/** Whether to skip logging a {@link TestSuite}. */
- public boolean ignoreSuite(TestSuite suite) {
+ public boolean ignoreSuite(@Nullable Kind kind, TestSuite suite) {
// by default only include innermost 'testsuite' elements
- return suite.testSuites.isEmpty();
+ return !suite.testSuites.isEmpty();
}
}
diff --git a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeXmlSchema.java b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeXmlSchema.java
index 4126bc8..f1f053a 100644
--- a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeXmlSchema.java
+++ b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeXmlSchema.java
@@ -18,6 +18,7 @@
import com.google.common.collect.Lists;
import java.io.InputStream;
import java.util.List;
+import java.util.Objects;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAttribute;
@@ -95,6 +96,40 @@
@XmlElement(name = "testcase")
List<TestCase> testCases = Lists.newArrayList();
+
+ /** Used to merge test suites from a single target, split across multiple shards */
+ private void addSuite(TestSuite suite) {
+ for (TestSuite existing : testSuites) {
+ if (Objects.equals(existing.name, suite.name)) {
+ existing.mergeWithSuite(suite);
+ return;
+ }
+ }
+ testSuites.add(suite);
+ }
+
+ private void mergeWithSuite(TestSuite suite) {
+ for (TestSuite child : suite.testSuites) {
+ addSuite(child);
+ }
+ testDecorators.addAll(suite.testDecorators);
+ testCases.addAll(suite.testCases);
+ tests += suite.tests;
+ failures += suite.failures;
+ errors += suite.errors;
+ skipped += suite.skipped;
+ disabled += suite.disabled;
+ time += suite.time;
+ }
+ }
+
+ /** Used to merge test suites from a single target, split across multiple shards */
+ static TestSuite mergeSuites(List<TestSuite> suites) {
+ TestSuite outer = new TestSuite();
+ for (TestSuite suite : suites) {
+ outer.addSuite(suite);
+ }
+ return outer;
}
static class TestCase {
diff --git a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeXmlToTestEventsConverter.java b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeXmlToTestEventsConverter.java
index 548557a..be9d154 100644
--- a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeXmlToTestEventsConverter.java
+++ b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeXmlToTestEventsConverter.java
@@ -15,6 +15,7 @@
*/
package com.google.idea.blaze.base.run.smrunner;
+import com.google.common.collect.ImmutableMultimap;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.model.primitives.Label;
@@ -23,7 +24,6 @@
import com.google.idea.blaze.base.run.smrunner.BlazeXmlSchema.TestSuite;
import com.google.idea.blaze.base.run.targetfinder.TargetFinder;
import com.google.idea.blaze.base.run.testlogs.BlazeTestXmlFinderStrategy;
-import com.google.idea.blaze.base.run.testlogs.CompletedTestTarget;
import com.google.idea.sdkcompat.smrunner.SmRunnerCompatUtils;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.testframework.TestConsoleProperties;
@@ -37,9 +37,13 @@
import com.intellij.execution.testframework.sm.runner.events.TestSuiteStartedEvent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
+import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import javax.annotation.Nullable;
import jetbrains.buildServer.messages.serviceMessages.ServiceMessageVisitor;
import jetbrains.buildServer.messages.serviceMessages.TestSuiteStarted;
@@ -87,14 +91,31 @@
onStartTesting();
getProcessor().onTestsReporterAttached();
- for (CompletedTestTarget testTarget : BlazeTestXmlFinderStrategy.locateTestXmlFiles(project)) {
- try (InputStream input = new FileInputStream(testTarget.testResultXml)) {
- parseXmlInput(getProcessor(), getKind(project, testTarget.label), input);
+ ImmutableMultimap<Label, File> xmlFiles =
+ BlazeTestXmlFinderStrategy.locateTestXmlFiles(project);
+ for (Label label : xmlFiles.keySet()) {
+ processTestSuites(label, xmlFiles.get(label));
+ }
+ }
+
+ /** Process all test XML files from a single test target. */
+ private void processTestSuites(Label label, Collection<File> files) {
+ Kind kind = getKind(project, label);
+ List<TestSuite> targetSuites = new ArrayList<>();
+ for (File file : files) {
+ try (InputStream input = new FileInputStream(file)) {
+ targetSuites.add(BlazeXmlSchema.parse(input));
} catch (Exception e) {
// ignore parsing errors -- most common cause is user cancellation, which we can't easily
// recognize.
}
}
+ if (targetSuites.isEmpty()) {
+ return;
+ }
+ TestSuite suite =
+ targetSuites.size() == 1 ? targetSuites.get(0) : BlazeXmlSchema.mergeSuites(targetSuites);
+ processTestSuite(getProcessor(), kind, suite);
}
@Nullable
@@ -103,19 +124,13 @@
return target != null ? target.kind : null;
}
- private void parseXmlInput(
- GeneralTestEventsProcessor processor, @Nullable Kind kind, InputStream input) {
- TestSuite testResult = BlazeXmlSchema.parse(input);
- processTestSuite(processor, kind, testResult);
- }
-
private void processTestSuite(
GeneralTestEventsProcessor processor, @Nullable Kind kind, TestSuite suite) {
if (!hasRunChild(suite)) {
return;
}
// only include the innermost 'testsuite' element
- boolean logSuite = !eventsHandler.ignoreSuite(suite);
+ boolean logSuite = !eventsHandler.ignoreSuite(kind, suite);
if (suite.name != null && logSuite) {
TestSuiteStarted suiteStarted =
new TestSuiteStarted(eventsHandler.suiteDisplayName(kind, suite.name));
diff --git a/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestXmlFinderStrategy.java b/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestXmlFinderStrategy.java
index 174d512..a069108 100644
--- a/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestXmlFinderStrategy.java
+++ b/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestXmlFinderStrategy.java
@@ -15,11 +15,13 @@
*/
package com.google.idea.blaze.base.run.testlogs;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
+import java.io.File;
/** A strategy for locating output test XML files. */
public interface BlazeTestXmlFinderStrategy {
@@ -28,25 +30,25 @@
ExtensionPointName.create("com.google.idea.blaze.BlazeTestXmlFinderStrategy");
/**
- * Attempt to find all output test XML files associated with the given run configuration. Called
- * after the 'blaze test' process completes.
+ * Attempt to find all output test XML files produced by the most recent blaze invocation, grouped
+ * by target label.
*/
- static ImmutableList<CompletedTestTarget> locateTestXmlFiles(Project project) {
+ static ImmutableMultimap<Label, File> locateTestXmlFiles(Project project) {
BuildSystem buildSystem = Blaze.getBuildSystem(project);
- ImmutableList.Builder<CompletedTestTarget> output = ImmutableList.builder();
+ ImmutableMultimap.Builder<Label, File> output = ImmutableMultimap.builder();
for (BlazeTestXmlFinderStrategy strategy : EP_NAME.getExtensions()) {
if (strategy.handlesBuildSystem(buildSystem)) {
- output.addAll(strategy.findTestXmlFiles(project));
+ output.putAll(strategy.findTestXmlFiles(project));
}
}
return output.build();
}
/**
- * Attempt to find all output test XML files associated with the given run configuration using a
- * particular strategy. Called after the 'blaze test' process completes.
+ * Attempt to find all output test XML files produced by the most recent blaze invocation, grouped
+ * by target label. Called after the 'blaze test' process completes.
*/
- ImmutableList<CompletedTestTarget> findTestXmlFiles(Project project);
+ ImmutableMultimap<Label, File> findTestXmlFiles(Project project);
boolean handlesBuildSystem(BuildSystem buildSystem);
}
diff --git a/base/src/com/google/idea/blaze/base/run/testlogs/TargetPathTestXmlFinderStrategy.java b/base/src/com/google/idea/blaze/base/run/testlogs/TargetPathTestXmlFinderStrategy.java
index ce5ec40..30b2b05 100644
--- a/base/src/com/google/idea/blaze/base/run/testlogs/TargetPathTestXmlFinderStrategy.java
+++ b/base/src/com/google/idea/blaze/base/run/testlogs/TargetPathTestXmlFinderStrategy.java
@@ -15,7 +15,7 @@
*/
package com.google.idea.blaze.base.run.testlogs;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMultimap;
import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.Label;
@@ -24,8 +24,6 @@
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.intellij.openapi.project.Project;
import java.io.File;
-import java.util.Objects;
-import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@@ -40,28 +38,29 @@
}
@Override
- public ImmutableList<CompletedTestTarget> findTestXmlFiles(Project project) {
+ public ImmutableMultimap<Label, File> findTestXmlFiles(Project project) {
File testLogsDir = getTestLogsTree(project);
if (testLogsDir == null) {
- return ImmutableList.of();
+ return ImmutableMultimap.of();
}
File commandLog = getCommandLog(project);
if (commandLog == null) {
- return ImmutableList.of();
+ return ImmutableMultimap.of();
}
- return ImmutableList.copyOf(
- BlazeCommandLogParser.parseTestTargets(commandLog)
- .stream()
- .map((label) -> toKindAndTestXml(testLogsDir, label))
- .filter(Objects::nonNull)
- .collect(Collectors.toList()));
+ ImmutableMultimap.Builder<Label, File> output = ImmutableMultimap.builder();
+ for (Label label : BlazeCommandLogParser.parseTestTargets(commandLog)) {
+ File testXml = findTestXml(testLogsDir, label);
+ if (testXml != null) {
+ output.put(label, testXml);
+ }
+ }
+ return output.build();
}
@Nullable
- private static CompletedTestTarget toKindAndTestXml(File testLogsDir, Label label) {
+ private static File findTestXml(File testLogsDir, Label label) {
String labelPath = label.blazePackage() + File.separator + label.targetName();
- File testXml = new File(testLogsDir, labelPath + File.separator + "test.xml");
- return new CompletedTestTarget(testXml, label);
+ return new File(testLogsDir, labelPath + File.separator + "test.xml");
}
@Nullable
diff --git a/base/src/com/google/idea/blaze/base/scope/BlazeContext.java b/base/src/com/google/idea/blaze/base/scope/BlazeContext.java
index 316c05b..f502c10 100644
--- a/base/src/com/google/idea/blaze/base/scope/BlazeContext.java
+++ b/base/src/com/google/idea/blaze/base/scope/BlazeContext.java
@@ -20,8 +20,8 @@
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import java.util.List;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Scoped operation context. */
public class BlazeContext {
diff --git a/base/src/com/google/idea/blaze/base/scope/Scope.java b/base/src/com/google/idea/blaze/base/scope/Scope.java
index 4c0f12a..27003e5 100644
--- a/base/src/com/google/idea/blaze/base/scope/Scope.java
+++ b/base/src/com/google/idea/blaze/base/scope/Scope.java
@@ -16,8 +16,8 @@
package com.google.idea.blaze.base.scope;
import com.intellij.openapi.diagnostic.Logger;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Helper methods to run scoped functions and operations in a scoped context. */
public final class Scope {
diff --git a/base/src/com/google/idea/blaze/base/scope/ScopedTask.java b/base/src/com/google/idea/blaze/base/scope/ScopedTask.java
index 725bf2f..877cbe8 100644
--- a/base/src/com/google/idea/blaze/base/scope/ScopedTask.java
+++ b/base/src/com/google/idea/blaze/base/scope/ScopedTask.java
@@ -18,15 +18,15 @@
import com.google.idea.blaze.base.scope.scopes.ProgressIndicatorScope;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Progressive;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Wrapper between an IntelliJ Task and a BlazeContext */
public abstract class ScopedTask implements Progressive {
@Nullable final BlazeContext parentContext;
public ScopedTask() {
- this(null /* parentContext */);
+ this(/* parentContext */ null);
}
public ScopedTask(@Nullable BlazeContext parentContext) {
diff --git a/base/src/com/google/idea/blaze/base/scope/output/IssueOutput.java b/base/src/com/google/idea/blaze/base/scope/output/IssueOutput.java
index e3bc15a..8690be2 100644
--- a/base/src/com/google/idea/blaze/base/scope/output/IssueOutput.java
+++ b/base/src/com/google/idea/blaze/base/scope/output/IssueOutput.java
@@ -19,8 +19,8 @@
import com.google.idea.blaze.base.scope.Output;
import com.intellij.pom.Navigatable;
import java.io.File;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** An issue in a blaze operation. */
public class IssueOutput implements Output {
diff --git a/base/src/com/google/idea/blaze/base/scope/scopes/BlazeConsoleScope.java b/base/src/com/google/idea/blaze/base/scope/scopes/BlazeConsoleScope.java
index 1875f20..7128856 100644
--- a/base/src/com/google/idea/blaze/base/scope/scopes/BlazeConsoleScope.java
+++ b/base/src/com/google/idea/blaze/base/scope/scopes/BlazeConsoleScope.java
@@ -28,8 +28,8 @@
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Moves print output to the blaze console. */
public class BlazeConsoleScope implements BlazeScope {
diff --git a/base/src/com/google/idea/blaze/base/scope/scopes/TimingScope.java b/base/src/com/google/idea/blaze/base/scope/scopes/TimingScope.java
index d3dcad0..bad8849 100644
--- a/base/src/com/google/idea/blaze/base/scope/scopes/TimingScope.java
+++ b/base/src/com/google/idea/blaze/base/scope/scopes/TimingScope.java
@@ -20,8 +20,8 @@
import com.google.idea.blaze.base.scope.BlazeScope;
import com.google.idea.blaze.base.scope.output.PrintOutput;
import java.util.List;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Prints timing information as output. */
public class TimingScope implements BlazeScope {
diff --git a/base/src/com/google/idea/blaze/base/settings/BlazeImportSettings.java b/base/src/com/google/idea/blaze/base/settings/BlazeImportSettings.java
index 7f0ea60..86194e8 100644
--- a/base/src/com/google/idea/blaze/base/settings/BlazeImportSettings.java
+++ b/base/src/com/google/idea/blaze/base/settings/BlazeImportSettings.java
@@ -16,13 +16,9 @@
package com.google.idea.blaze.base.settings;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
-import com.intellij.util.xmlb.annotations.Tag;
import javax.annotation.Nullable;
-// The tag here is for legacy migration support.
-// No longer needed and can be removed with {@link BlazeImportSettingsManagerLegacy}
/** Project settings that are set at import time. */
-@Tag("BlazeProjectSettings")
public final class BlazeImportSettings {
private String workspaceRoot = "";
diff --git a/base/src/com/google/idea/blaze/base/settings/BlazeImportSettingsManager.java b/base/src/com/google/idea/blaze/base/settings/BlazeImportSettingsManager.java
index a45b08e..093b18a 100644
--- a/base/src/com/google/idea/blaze/base/settings/BlazeImportSettingsManager.java
+++ b/base/src/com/google/idea/blaze/base/settings/BlazeImportSettingsManager.java
@@ -21,8 +21,8 @@
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.project.Project;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Manages storage for the project's {@link BlazeImportSettings}. */
@State(name = "BlazeImportSettings", storages = @Storage(file = StoragePathMacros.WORKSPACE_FILE))
@@ -30,11 +30,7 @@
@Nullable private BlazeImportSettings importSettings;
- private Project project;
-
- public BlazeImportSettingsManager(@NotNull Project project) {
- this.project = project;
- }
+ public BlazeImportSettingsManager() {}
public static BlazeImportSettingsManager getInstance(Project project) {
return ServiceManager.getService(project, BlazeImportSettingsManager.class);
@@ -54,11 +50,6 @@
@Nullable
public BlazeImportSettings getImportSettings() {
- if (importSettings == null) {
- importSettings =
- BlazeImportSettingsManagerLegacy.getInstance(project).migrateImportSettings();
- }
-
return importSettings;
}
diff --git a/base/src/com/google/idea/blaze/base/settings/BlazeImportSettingsManagerLegacy.java b/base/src/com/google/idea/blaze/base/settings/BlazeImportSettingsManagerLegacy.java
deleted file mode 100644
index fec7d1d..0000000
--- a/base/src/com/google/idea/blaze/base/settings/BlazeImportSettingsManagerLegacy.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.settings;
-
-import com.google.common.collect.Lists;
-import com.intellij.openapi.components.PersistentStateComponent;
-import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.components.State;
-import com.intellij.openapi.components.Storage;
-import com.intellij.openapi.components.StoragePathMacros;
-import com.intellij.openapi.components.StorageScheme;
-import com.intellij.openapi.project.Project;
-import com.intellij.util.xmlb.annotations.AbstractCollection;
-import java.util.Collection;
-import java.util.List;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Legacy storage for BlazeImportSettings. Introduced in 1.8, can be removed around ~2.2. Removal of
- * this class will cause old projects to stop loading.
- */
-@State(
- name = "BlazeSettings",
- storages = {
- @Storage(file = StoragePathMacros.PROJECT_FILE),
- @Storage(
- file = StoragePathMacros.PROJECT_CONFIG_DIR + "/blaze.xml",
- scheme = StorageScheme.DIRECTORY_BASED
- )
- }
-)
-public class BlazeImportSettingsManagerLegacy
- implements PersistentStateComponent<BlazeImportSettingsManagerLegacy.State> {
-
- @Nullable private BlazeImportSettings importSettings;
-
- @NotNull private Project project;
-
- public BlazeImportSettingsManagerLegacy(@NotNull Project project) {
- this.project = project;
- }
-
- @NotNull
- public static BlazeImportSettingsManagerLegacy getInstance(@NotNull Project project) {
- return ServiceManager.getService(project, BlazeImportSettingsManagerLegacy.class);
- }
-
- @SuppressWarnings("unchecked")
- @Nullable
- @Override
- public State getState() {
- if (importSettings == null) {
- return null;
- }
- State state = new State();
- List<BlazeImportSettings> value = Lists.newArrayList();
- value.add(importSettings);
- state.setLinkedExternalProjectsSettings(value);
- return state;
- }
-
- @Override
- public void loadState(State state) {
- if (state == null) {
- importSettings = null;
- return;
- }
-
- Collection<BlazeImportSettings> settings = state.getLinkedExternalProjectsSettings();
- if (settings != null && !settings.isEmpty()) {
- importSettings = settings.iterator().next();
- } else {
- importSettings = null;
- }
- }
-
- @Nullable
- BlazeImportSettings migrateImportSettings() {
- BlazeImportSettings importSettings = this.importSettings;
- this.importSettings = null;
- return importSettings;
- }
-
- /** State class for the Blaze settings. */
- static class State {
-
- private List<BlazeImportSettings> importSettings = Lists.newArrayList();
-
- @AbstractCollection(
- surroundWithTag = false,
- elementTypes = {BlazeImportSettings.class}
- )
- public List<BlazeImportSettings> getLinkedExternalProjectsSettings() {
- return importSettings;
- }
-
- public void setLinkedExternalProjectsSettings(List<BlazeImportSettings> settings) {
- importSettings = settings;
- }
- }
-}
diff --git a/base/src/com/google/idea/blaze/base/sync/BlazeSyncTask.java b/base/src/com/google/idea/blaze/base/sync/BlazeSyncTask.java
index 9b6849f..5504048 100644
--- a/base/src/com/google/idea/blaze/base/sync/BlazeSyncTask.java
+++ b/base/src/com/google/idea/blaze/base/sync/BlazeSyncTask.java
@@ -16,7 +16,6 @@
package com.google.idea.blaze.base.sync;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
@@ -26,6 +25,7 @@
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.idea.blaze.base.async.FutureUtil;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
+import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.experiments.ExperimentScope;
import com.google.idea.blaze.base.filecache.FileCaches;
@@ -72,6 +72,7 @@
import com.google.idea.blaze.base.sync.libraries.BlazeLibraryCollector;
import com.google.idea.blaze.base.sync.libraries.LibraryEditor;
import com.google.idea.blaze.base.sync.projectstructure.ContentEntryEditor;
+import com.google.idea.blaze.base.sync.projectstructure.DirectoryStructure;
import com.google.idea.blaze.base.sync.projectstructure.ModuleEditorImpl;
import com.google.idea.blaze.base.sync.projectstructure.ModuleEditorProvider;
import com.google.idea.blaze.base.sync.projectview.ImportRoots;
@@ -208,12 +209,23 @@
return SyncResult.FAILURE;
}
+ ListeningExecutorService executor = BlazeExecutor.getInstance().getExecutor();
+ WorkspacePathResolverAndProjectView workspacePathResolverAndProjectView =
+ computeWorkspacePathResolverAndProjectView(context, vcsHandler, executor);
+ if (workspacePathResolverAndProjectView == null) {
+ return SyncResult.FAILURE;
+ }
+ ProjectViewSet projectViewSet = workspacePathResolverAndProjectView.projectViewSet;
+
ListenableFuture<ImmutableMap<String, String>> blazeInfoFuture =
BlazeInfo.getInstance()
.runBlazeInfo(
- context, importSettings.getBuildSystem(), workspaceRoot, ImmutableList.of());
+ context,
+ Blaze.getBuildSystemProvider(project).getSyncBinaryPath(),
+ workspaceRoot,
+ BlazeFlags.buildFlags(project, projectViewSet));
- ListeningExecutorService executor = BlazeExecutor.getInstance().getExecutor();
+
ListenableFuture<WorkingSet> workingSetFuture =
vcsHandler.getWorkingSet(project, context, workspaceRoot, executor);
@@ -228,21 +240,14 @@
if (blazeInfo == null) {
return SyncResult.FAILURE;
}
- BlazeRoots blazeRoots =
- BlazeRoots.build(importSettings.getBuildSystem(), workspaceRoot, blazeInfo);
+ BlazeRoots blazeRoots = BlazeRoots.build(importSettings.getBuildSystem(), blazeInfo);
BlazeVersionData blazeVersionData =
BlazeVersionData.build(importSettings.getBuildSystem(), workspaceRoot, blazeInfo);
- WorkspacePathResolverAndProjectView workspacePathResolverAndProjectView =
- computeWorkspacePathResolverAndProjectView(context, blazeRoots, vcsHandler, executor);
- if (workspacePathResolverAndProjectView == null) {
- return SyncResult.FAILURE;
- }
WorkspacePathResolver workspacePathResolver =
workspacePathResolverAndProjectView.workspacePathResolver;
ArtifactLocationDecoder artifactLocationDecoder =
new ArtifactLocationDecoderImpl(blazeRoots, workspacePathResolver);
- ProjectViewSet projectViewSet = workspacePathResolverAndProjectView.projectViewSet;
WorkspaceLanguageSettings workspaceLanguageSettings =
LanguageSupport.createWorkspaceLanguageSettings(context, projectViewSet);
@@ -396,11 +401,30 @@
.onError("Prefetch failed")
.run();
+ ListenableFuture<DirectoryStructure> directoryStructureFuture =
+ DirectoryStructure.getRootDirectoryStructure(project, workspaceRoot, projectViewSet);
+
refreshVirtualFileSystem(context, newBlazeProjectData);
+ DirectoryStructure directoryStructure =
+ FutureUtil.waitForFuture(context, directoryStructureFuture)
+ .withProgressMessage("Computing directory structure...")
+ .timed("DirectoryStructure")
+ .onError("Directory structure computation failed")
+ .run()
+ .result();
+ if (directoryStructure == null) {
+ return SyncResult.FAILURE;
+ }
+
boolean success =
updateProject(
- context, projectViewSet, blazeVersionData, oldBlazeProjectData, newBlazeProjectData);
+ context,
+ projectViewSet,
+ blazeVersionData,
+ directoryStructure,
+ oldBlazeProjectData,
+ newBlazeProjectData);
if (!success) {
return SyncResult.FAILURE;
}
@@ -458,7 +482,6 @@
private WorkspacePathResolverAndProjectView computeWorkspacePathResolverAndProjectView(
BlazeContext context,
- BlazeRoots blazeRoots,
BlazeVcsHandler vcsHandler,
ListeningExecutorService executor) {
context.output(new StatusOutput("Updating VCS..."));
@@ -484,7 +507,7 @@
WorkspacePathResolver workspacePathResolver =
vcsWorkspacePathResolver != null
? vcsWorkspacePathResolver
- : new WorkspacePathResolverImpl(workspaceRoot, blazeRoots);
+ : new WorkspacePathResolverImpl(workspaceRoot);
ProjectViewSet projectViewSet =
ProjectViewManager.getInstance(project).reloadProjectView(context, workspacePathResolver);
@@ -639,6 +662,7 @@
BlazeContext parentContext,
ProjectViewSet projectViewSet,
BlazeVersionData blazeVersionData,
+ DirectoryStructure directoryStructure,
@Nullable BlazeProjectData oldBlazeProjectData,
BlazeProjectData newBlazeProjectData) {
return Scope.push(
@@ -656,19 +680,15 @@
() ->
ProjectRootManagerEx.getInstanceEx(this.project)
.mergeRootsChangesDuring(
- () -> {
- updateProjectSdk(
- context,
- projectViewSet,
- blazeVersionData,
- newBlazeProjectData);
- updateProjectStructure(
- context,
- importSettings,
- projectViewSet,
- newBlazeProjectData,
- oldBlazeProjectData);
- })));
+ () ->
+ updateProjectStructure(
+ context,
+ importSettings,
+ projectViewSet,
+ blazeVersionData,
+ directoryStructure,
+ newBlazeProjectData,
+ oldBlazeProjectData))));
} catch (Throwable e) {
IssueOutput.error("Internal error. Error: " + e).submit(context);
logger.error(e);
@@ -681,24 +701,20 @@
});
}
- private void updateProjectSdk(
- BlazeContext context,
- ProjectViewSet projectViewSet,
- BlazeVersionData blazeVersionData,
- BlazeProjectData newBlazeProjectData) {
- for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
- syncPlugin.updateProjectSdk(
- project, context, projectViewSet, blazeVersionData, newBlazeProjectData);
- }
- }
-
private void updateProjectStructure(
BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
+ BlazeVersionData blazeVersionData,
+ DirectoryStructure directoryStructure,
BlazeProjectData newBlazeProjectData,
@Nullable BlazeProjectData oldBlazeProjectData) {
+ for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
+ syncPlugin.updateProjectSdk(
+ project, context, projectViewSet, blazeVersionData, newBlazeProjectData);
+ }
+
ModuleEditorImpl moduleEditor =
ModuleEditorProvider.getInstance().getModuleEditor(project, importSettings);
@@ -721,7 +737,12 @@
ModifiableRootModel workspaceModifiableModel = moduleEditor.editModule(workspaceModule);
ContentEntryEditor.createContentEntries(
- project, workspaceRoot, projectViewSet, newBlazeProjectData, workspaceModifiableModel);
+ project,
+ workspaceRoot,
+ projectViewSet,
+ newBlazeProjectData,
+ directoryStructure,
+ workspaceModifiableModel);
List<BlazeLibrary> libraries = BlazeLibraryCollector.getLibraries(newBlazeProjectData);
LibraryEditor.updateProjectLibraries(project, context, newBlazeProjectData, libraries);
diff --git a/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java b/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java
index 12a09c5..ac83b63 100644
--- a/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java
+++ b/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java
@@ -26,6 +26,7 @@
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.async.process.ExternalTask;
import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
+import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
@@ -49,7 +50,6 @@
import com.google.idea.blaze.base.scope.output.PrintOutput;
import com.google.idea.blaze.base.scope.scopes.TimingScope;
import com.google.idea.blaze.base.settings.Blaze;
-import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategy;
import com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategyProvider;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
@@ -192,9 +192,8 @@
List<File> result = Lists.newArrayList();
- BuildSystem buildSystem = Blaze.getBuildSystem(project);
BlazeCommand.Builder blazeCommandBuilder =
- BlazeCommand.builder(buildSystem, BlazeCommandName.BUILD);
+ BlazeCommand.builder(getBinaryPath(project), BlazeCommandName.BUILD);
blazeCommandBuilder.addTargets(targets);
blazeCommandBuilder.addBlazeFlags(BlazeFlags.KEEP_GOING);
blazeCommandBuilder
@@ -409,7 +408,7 @@
AspectStrategy aspectStrategy = getAspectStrategy(project, blazeVersionData);
BlazeCommand.Builder blazeCommandBuilder =
- BlazeCommand.builder(Blaze.getBuildSystem(project), BlazeCommandName.BUILD)
+ BlazeCommand.builder(getBinaryPath(project), BlazeCommandName.BUILD)
.addTargets(targets)
.addBlazeFlags()
.addBlazeFlags(BlazeFlags.KEEP_GOING)
@@ -447,4 +446,9 @@
// Should never get here
throw new IllegalStateException("No aspect strategy found.");
}
+
+ private static String getBinaryPath(Project project) {
+ BuildSystemProvider buildSystemProvider = Blaze.getBuildSystemProvider(project);
+ return buildSystemProvider.getSyncBinaryPath();
+ }
}
diff --git a/base/src/com/google/idea/blaze/base/sync/aspects/strategy/AspectStrategyProviderBazel.java b/base/src/com/google/idea/blaze/base/sync/aspects/strategy/AspectStrategyProviderBazel.java
index 180ae9e..c8a4920 100644
--- a/base/src/com/google/idea/blaze/base/sync/aspects/strategy/AspectStrategyProviderBazel.java
+++ b/base/src/com/google/idea/blaze/base/sync/aspects/strategy/AspectStrategyProviderBazel.java
@@ -21,12 +21,12 @@
class AspectStrategyProviderBazel implements AspectStrategyProvider {
private static final BoolExperiment useSkylarkAspect =
- new BoolExperiment("use.skylark.aspect.bazel.2", true);
+ new BoolExperiment("use.skylark.aspect.bazel.3", true);
@Override
public AspectStrategy getAspectStrategy(Project project, BlazeVersionData blazeVersionData) {
boolean canUseSkylark =
- useSkylarkAspect.getValue() && blazeVersionData.bazelIsAtLeastVersion(0, 4, 4);
+ useSkylarkAspect.getValue() && blazeVersionData.bazelIsAtLeastVersion(0, 4, 5);
return canUseSkylark ? new AspectStrategySkylark() : new AspectStrategyNative();
}
diff --git a/base/src/com/google/idea/blaze/base/sync/projectstructure/ContentEntryEditor.java b/base/src/com/google/idea/blaze/base/sync/projectstructure/ContentEntryEditor.java
index 5b76a0c..b179a7d 100644
--- a/base/src/com/google/idea/blaze/base/sync/projectstructure/ContentEntryEditor.java
+++ b/base/src/com/google/idea/blaze/base/sync/projectstructure/ContentEntryEditor.java
@@ -19,7 +19,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
-import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
@@ -36,6 +35,7 @@
import java.io.File;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
/** Modifies content entries based on project data. */
public class ContentEntryEditor {
@@ -45,6 +45,7 @@
WorkspaceRoot workspaceRoot,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
+ DirectoryStructure rootDirectoryStructure,
ModifiableRootModel modifiableRootModel) {
ImportRoots importRoots =
ImportRoots.builder(workspaceRoot, Blaze.getBuildSystem(project))
@@ -60,9 +61,9 @@
List<ContentEntry> contentEntries = Lists.newArrayList();
for (WorkspacePath rootDirectory : rootDirectories) {
- File root = workspaceRoot.fileForPath(rootDirectory);
+ File rootFile = workspaceRoot.fileForPath(rootDirectory);
ContentEntry contentEntry =
- modifiableRootModel.addContentEntry(UrlUtil.pathToUrl(root.getPath()));
+ modifiableRootModel.addContentEntry(UrlUtil.pathToUrl(rootFile.getPath()));
contentEntries.add(contentEntry);
for (WorkspacePath exclude : excludesByRootDirectory.get(rootDirectory)) {
@@ -72,7 +73,7 @@
ImmutableMap<File, SourceFolder> sourceFolders =
provider.initializeSourceFolders(contentEntry);
- SourceFolder rootSource = sourceFolders.get(root);
+ SourceFolder rootSource = sourceFolders.get(rootFile);
walkFileSystem(
workspaceRoot,
testConfig,
@@ -81,7 +82,8 @@
provider,
sourceFolders,
rootSource,
- root);
+ rootDirectory,
+ rootDirectoryStructure.directories.get(rootDirectory));
}
}
@@ -93,20 +95,12 @@
SourceFolderProvider provider,
ImmutableMap<File, SourceFolder> sourceFolders,
SourceFolder parent,
- File file) {
- if (!FileAttributeProvider.getInstance().isDirectory(file)) {
- return;
- }
- WorkspacePath workspacePath;
- try {
- workspacePath = workspaceRoot.workspacePathFor(file);
- } catch (IllegalArgumentException e) {
- // stop at directories with unhandled characters.
- return;
- }
+ WorkspacePath workspacePath,
+ DirectoryStructure directoryStructure) {
if (excludedDirectories.contains(workspacePath)) {
return;
}
+ File file = workspaceRoot.fileForPath(workspacePath);
boolean isTest = testConfig.isTestSource(workspacePath.relativePath());
SourceFolder current = sourceFolders.get(new File(file.getPath()));
SourceFolder currentOrParent = current != null ? current : parent;
@@ -117,11 +111,8 @@
contentEntry.removeSourceFolder(current);
}
}
- File[] children = FileAttributeProvider.getInstance().listFiles(file);
- if (children == null) {
- return;
- }
- for (File child : children) {
+ for (Map.Entry<WorkspacePath, DirectoryStructure> child :
+ directoryStructure.directories.entrySet()) {
walkFileSystem(
workspaceRoot,
testConfig,
@@ -130,7 +121,8 @@
provider,
sourceFolders,
currentOrParent,
- child);
+ child.getKey(),
+ child.getValue());
}
}
diff --git a/base/src/com/google/idea/blaze/base/sync/projectstructure/DirectoryStructure.java b/base/src/com/google/idea/blaze/base/sync/projectstructure/DirectoryStructure.java
new file mode 100644
index 0000000..827e13e
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/sync/projectstructure/DirectoryStructure.java
@@ -0,0 +1,89 @@
+/*
+ * 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.sync.projectstructure;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.idea.blaze.base.io.FileAttributeProvider;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.prefetch.FetchExecutor;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.sync.projectview.ImportRoots;
+import com.intellij.openapi.project.Project;
+import java.io.File;
+import java.util.Collection;
+
+/**
+ * Directory structure representation used by {@link ContentEntryEditor}.
+ *
+ * <p>The purpose of this class is to pull out all file system operations out of the project
+ * structure commit step, as this step locks the UI.
+ */
+public class DirectoryStructure {
+
+ final ImmutableMap<WorkspacePath, DirectoryStructure> directories;
+
+ private DirectoryStructure(ImmutableMap<WorkspacePath, DirectoryStructure> directories) {
+ this.directories = directories;
+ }
+
+ public static ListenableFuture<DirectoryStructure> getRootDirectoryStructure(
+ Project project, WorkspaceRoot workspaceRoot, ProjectViewSet projectViewSet) {
+ return FetchExecutor.EXECUTOR.submit(
+ () -> computeRootDirectoryStructure(project, workspaceRoot, projectViewSet));
+ }
+
+ private static DirectoryStructure computeRootDirectoryStructure(
+ Project project, WorkspaceRoot workspaceRoot, ProjectViewSet projectViewSet) {
+ ImportRoots importRoots =
+ ImportRoots.builder(workspaceRoot, Blaze.getBuildSystem(project))
+ .add(projectViewSet)
+ .build();
+ Collection<WorkspacePath> rootDirectories = importRoots.rootDirectories();
+ ImmutableMap.Builder<WorkspacePath, DirectoryStructure> result = ImmutableMap.builder();
+ for (WorkspacePath rootDirectory : rootDirectories) {
+ walkDirectoryStructure(workspaceRoot, result, rootDirectory);
+ }
+ return new DirectoryStructure(result.build());
+ }
+
+ private static void walkDirectoryStructure(
+ WorkspaceRoot workspaceRoot,
+ ImmutableMap.Builder<WorkspacePath, DirectoryStructure> parent,
+ WorkspacePath workspacePath) {
+ File file = workspaceRoot.fileForPath(workspacePath);
+ if (!FileAttributeProvider.getInstance().isDirectory(file)) {
+ return;
+ }
+ ImmutableMap.Builder<WorkspacePath, DirectoryStructure> result = ImmutableMap.builder();
+ File[] children = FileAttributeProvider.getInstance().listFiles(file);
+ if (children != null) {
+ for (File child : children) {
+ WorkspacePath childWorkspacePath;
+ try {
+ childWorkspacePath = workspaceRoot.workspacePathFor(child);
+ } catch (IllegalArgumentException e) {
+ // stop at directories with unhandled characters.
+ continue;
+ }
+ walkDirectoryStructure(workspaceRoot, result, childWorkspacePath);
+ }
+ }
+ parent.put(workspacePath, new DirectoryStructure(result.build()));
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/sync/status/BlazeSyncStatusImpl.java b/base/src/com/google/idea/blaze/base/sync/status/BlazeSyncStatusImpl.java
index ee60cd7..5f74602 100644
--- a/base/src/com/google/idea/blaze/base/sync/status/BlazeSyncStatusImpl.java
+++ b/base/src/com/google/idea/blaze/base/sync/status/BlazeSyncStatusImpl.java
@@ -37,8 +37,8 @@
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* Per-project listener for changes to BUILD files, and other changes requiring an incremental sync.
diff --git a/base/src/com/google/idea/blaze/base/sync/workspace/BlazeRoots.java b/base/src/com/google/idea/blaze/base/sync/workspace/BlazeRoots.java
index c66d024..26a00a2 100644
--- a/base/src/com/google/idea/blaze/base/sync/workspace/BlazeRoots.java
+++ b/base/src/com/google/idea/blaze/base/sync/workspace/BlazeRoots.java
@@ -17,43 +17,31 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
import com.google.idea.blaze.base.command.info.BlazeInfo;
-import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
-import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.intellij.openapi.diagnostic.Logger;
import java.io.File;
import java.io.Serializable;
-import java.util.List;
/** The data output by BlazeInfo. */
public class BlazeRoots implements Serializable {
public static final long serialVersionUID = 3L;
private static final Logger logger = Logger.getInstance(BlazeRoots.class);
- public static BlazeRoots build(
- BuildSystem buildSystem,
- WorkspaceRoot workspaceRoot,
- ImmutableMap<String, String> blazeInfo) {
+ public static BlazeRoots build(BuildSystem buildSystem, ImmutableMap<String, String> blazeInfo) {
return build(
- workspaceRoot,
getOrThrow(buildSystem, blazeInfo, BlazeInfo.EXECUTION_ROOT_KEY),
- getOrThrow(buildSystem, blazeInfo, BlazeInfo.PACKAGE_PATH_KEY),
getOrThrow(buildSystem, blazeInfo, BlazeInfo.blazeBinKey(buildSystem)),
getOrThrow(buildSystem, blazeInfo, BlazeInfo.blazeGenfilesKey(buildSystem)),
getOrThrow(buildSystem, blazeInfo, BlazeInfo.OUTPUT_BASE_KEY));
}
private static BlazeRoots build(
- WorkspaceRoot workspaceRoot,
String execRootString,
- String packagePathString,
String blazeBinRoot,
String blazeGenfilesRoot,
String externalSourceRoot) {
- List<File> packagePaths = parsePackagePaths(workspaceRoot.toString(), packagePathString.trim());
File executionRoot = new File(execRootString.trim());
ExecutionRootPath blazeBinExecutionRootPath =
ExecutionRootPath.createAncestorRelativePath(executionRoot, new File(blazeBinRoot));
@@ -64,7 +52,6 @@
logger.assertTrue(blazeGenfilesExecutionRootPath != null);
return new BlazeRoots(
executionRoot,
- packagePaths,
blazeBinExecutionRootPath,
blazeGenfilesExecutionRootPath,
externalSourceRootFile);
@@ -80,21 +67,7 @@
return value;
}
- private static List<File> parsePackagePaths(String workspaceRoot, String packagePathString) {
- String[] paths = packagePathString.split(":");
- List<File> packagePaths = Lists.newArrayListWithCapacity(paths.length);
- FileAttributeProvider fileAttributeProvider = FileAttributeProvider.getInstance();
- for (String path : paths) {
- File packagePath = new File(path.replace("%workspace%", workspaceRoot));
- if (fileAttributeProvider.exists(packagePath)) {
- packagePaths.add(packagePath);
- }
- }
- return packagePaths;
- }
-
public final File executionRoot;
- public final List<File> packagePaths;
public final ExecutionRootPath blazeBinExecutionRootPath;
public final ExecutionRootPath blazeGenfilesExecutionRootPath;
public final File externalSourceRoot;
@@ -102,12 +75,10 @@
@VisibleForTesting
public BlazeRoots(
File executionRoot,
- List<File> packagePaths,
ExecutionRootPath blazeBinExecutionRootPath,
ExecutionRootPath blazeGenfilesExecutionRootPath,
File externalSourceRoot) {
this.executionRoot = executionRoot;
- this.packagePaths = packagePaths;
this.blazeBinExecutionRootPath = blazeBinExecutionRootPath;
this.blazeGenfilesExecutionRootPath = blazeGenfilesExecutionRootPath;
this.externalSourceRoot = externalSourceRoot;
diff --git a/base/src/com/google/idea/blaze/base/sync/workspace/ExecutionRootPathResolver.java b/base/src/com/google/idea/blaze/base/sync/workspace/ExecutionRootPathResolver.java
index c6b7eef..c1b3f29 100644
--- a/base/src/com/google/idea/blaze/base/sync/workspace/ExecutionRootPathResolver.java
+++ b/base/src/com/google/idea/blaze/base/sync/workspace/ExecutionRootPathResolver.java
@@ -16,11 +16,12 @@
package com.google.idea.blaze.base.sync.workspace;
import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
-import com.intellij.openapi.util.io.FileUtil;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import java.io.File;
-import java.util.List;
/**
* Converts execution-root-relative paths to absolute files with a minimum of file system calls
@@ -31,15 +32,29 @@
*/
public class ExecutionRootPathResolver {
- private final BlazeRoots blazeRoots;
+ private final ImmutableList<String> buildArtifactDirectories;
+ private final File executionRoot;
private final WorkspacePathResolver workspacePathResolver;
public ExecutionRootPathResolver(
- BlazeRoots blazeRoots, WorkspacePathResolver workspacePathResolver) {
- this.blazeRoots = blazeRoots;
+ BuildSystem buildSystem,
+ WorkspaceRoot workspaceRoot,
+ File executionRoot,
+ WorkspacePathResolver workspacePathResolver) {
+ this.buildArtifactDirectories = buildArtifactDirectories(buildSystem, workspaceRoot);
+ this.executionRoot = executionRoot;
this.workspacePathResolver = workspacePathResolver;
}
+ private static ImmutableList<String> buildArtifactDirectories(
+ BuildSystem buildSystem, WorkspaceRoot workspaceRoot) {
+ BuildSystemProvider provider = BuildSystemProvider.getBuildSystemProvider(buildSystem);
+ if (provider == null) {
+ provider = BuildSystemProvider.defaultBuildSystem();
+ }
+ return provider.buildArtifactDirectories(workspaceRoot);
+ }
+
/**
* This method should be used for directories. Returns all workspace files corresponding to the
* given execution-root-relative path. If the file does not exist inside the workspace (e.g. for
@@ -53,19 +68,21 @@
WorkspacePath workspacePath = new WorkspacePath(path.getAbsoluteOrRelativeFile().getPath());
return workspacePathResolver.resolveToIncludeDirectories(workspacePath);
}
- return ImmutableList.of(path.getFileRootedAt(blazeRoots.executionRoot));
+ return ImmutableList.of(path.getFileRootedAt(executionRoot));
}
private boolean isInWorkspace(ExecutionRootPath path) {
- boolean inOutputDir =
- ExecutionRootPath.isAncestor(blazeRoots.blazeBinExecutionRootPath, path, false)
- || ExecutionRootPath.isAncestor(blazeRoots.blazeGenfilesExecutionRootPath, path, false)
- || isExternalWorkspacePath(path);
- return !inOutputDir;
+ String firstPathComponent = getFirstPathComponent(path.getAbsoluteOrRelativeFile().getPath());
+ return !buildArtifactDirectories.contains(firstPathComponent)
+ && !isExternalWorkspacePath(firstPathComponent);
}
- private static boolean isExternalWorkspacePath(ExecutionRootPath path) {
- List<String> pathComponents = FileUtil.splitPath(path.getAbsoluteOrRelativeFile().getPath());
- return pathComponents.size() > 1 && "external".equals(pathComponents.get(0));
+ private static String getFirstPathComponent(String path) {
+ int index = path.indexOf(File.separatorChar);
+ return index == -1 ? path : path.substring(0, index);
+ }
+
+ private static boolean isExternalWorkspacePath(String firstPathComponent) {
+ return firstPathComponent.equals("external");
}
}
diff --git a/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImpl.java b/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImpl.java
index ac131c1..48b4ddc 100644
--- a/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImpl.java
+++ b/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImpl.java
@@ -16,31 +16,19 @@
package com.google.idea.blaze.base.sync.workspace;
import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import java.io.File;
-import java.util.List;
import javax.annotation.Nullable;
/** Uses the package path locations to resolve a workspace path. */
public class WorkspacePathResolverImpl implements WorkspacePathResolver {
- private static final long serialVersionUID = 2L;
+ private static final long serialVersionUID = 3L;
private final WorkspaceRoot workspaceRoot;
- private final List<File> packagePaths;
-
- public WorkspacePathResolverImpl(WorkspaceRoot workspaceRoot, BlazeRoots blazeRoots) {
- this(workspaceRoot, blazeRoots.packagePaths);
- }
public WorkspacePathResolverImpl(WorkspaceRoot workspaceRoot) {
- this(workspaceRoot, ImmutableList.of(workspaceRoot.directory()));
- }
-
- public WorkspacePathResolverImpl(WorkspaceRoot workspaceRoot, List<File> packagePaths) {
this.workspaceRoot = workspaceRoot;
- this.packagePaths = packagePaths;
}
@Override
@@ -50,19 +38,7 @@
@Override
public File findPackageRoot(String relativePath) {
- if (packagePaths.size() == 1) {
- return packagePaths.get(0);
- }
- // fall back to manually checking each one
- FileAttributeProvider existenceChecker = FileAttributeProvider.getInstance();
- for (File pkg : packagePaths) {
- if (existenceChecker.exists(new File(pkg, relativePath))) {
- return pkg;
- }
- }
-
- // Return first in package path, even though it might not exist
- return packagePaths.get(0);
+ return workspaceRoot.directory();
}
@Nullable
diff --git a/base/src/com/google/idea/blaze/base/treeview/BlazeTreeStructureProvider.java b/base/src/com/google/idea/blaze/base/treeview/BlazeTreeStructureProvider.java
index 764e3b0..712c1fc 100644
--- a/base/src/com/google/idea/blaze/base/treeview/BlazeTreeStructureProvider.java
+++ b/base/src/com/google/idea/blaze/base/treeview/BlazeTreeStructureProvider.java
@@ -36,8 +36,8 @@
import java.io.File;
import java.util.Collection;
import java.util.List;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* Modifies the project view:
@@ -147,6 +147,9 @@
@Override
public boolean isShowExcludedFiles() {
+ if (original instanceof ProjectViewSettings) {
+ return ((ProjectViewSettings) original).isShowExcludedFiles();
+ }
return true;
}
};
diff --git a/base/src/com/google/idea/blaze/base/ui/BlazeValidationError.java b/base/src/com/google/idea/blaze/base/ui/BlazeValidationError.java
index 452ae82..f79fffc 100644
--- a/base/src/com/google/idea/blaze/base/ui/BlazeValidationError.java
+++ b/base/src/com/google/idea/blaze/base/ui/BlazeValidationError.java
@@ -18,9 +18,9 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import java.util.Collection;
+import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** An error occuring during a blaze validation */
@Immutable
diff --git a/base/src/com/google/idea/blaze/base/ui/BlazeValidationResult.java b/base/src/com/google/idea/blaze/base/ui/BlazeValidationResult.java
index 4200003..b6bc270 100644
--- a/base/src/com/google/idea/blaze/base/ui/BlazeValidationResult.java
+++ b/base/src/com/google/idea/blaze/base/ui/BlazeValidationResult.java
@@ -15,7 +15,7 @@
*/
package com.google.idea.blaze.base.ui;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Pair of (success, validation error) */
public class BlazeValidationResult {
diff --git a/base/src/com/google/idea/blaze/base/util/SerializationUtil.java b/base/src/com/google/idea/blaze/base/util/SerializationUtil.java
index f098673..ea689da 100644
--- a/base/src/com/google/idea/blaze/base/util/SerializationUtil.java
+++ b/base/src/com/google/idea/blaze/base/util/SerializationUtil.java
@@ -17,7 +17,6 @@
import com.google.common.io.Closeables;
import com.intellij.CommonBundle;
-import com.intellij.openapi.diagnostic.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -26,12 +25,11 @@
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.Serializable;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Utils for serialization. */
public class SerializationUtil {
- private static final Logger logger = Logger.getInstance(SerializationUtil.class.getName());
public static void saveToDisk(@NotNull File file, @NotNull Serializable serializable)
throws IOException {
diff --git a/base/src/com/google/idea/blaze/base/wizard2/BlazeWizardUserSettingsStorage.java b/base/src/com/google/idea/blaze/base/wizard2/BlazeWizardUserSettingsStorage.java
index 2184d14..0ff0440 100644
--- a/base/src/com/google/idea/blaze/base/wizard2/BlazeWizardUserSettingsStorage.java
+++ b/base/src/com/google/idea/blaze/base/wizard2/BlazeWizardUserSettingsStorage.java
@@ -19,7 +19,7 @@
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Stores wizard user settings between runs. */
@State(name = "BlazeWizardUserSettings", storages = @Storage("blaze.wizard.settings.xml"))
diff --git a/base/src/com/google/idea/blaze/base/wizard2/ui/BlazeEditProjectViewControl.java b/base/src/com/google/idea/blaze/base/wizard2/ui/BlazeEditProjectViewControl.java
index e936db3..70001eb 100644
--- a/base/src/com/google/idea/blaze/base/wizard2/ui/BlazeEditProjectViewControl.java
+++ b/base/src/com/google/idea/blaze/base/wizard2/ui/BlazeEditProjectViewControl.java
@@ -68,11 +68,11 @@
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** The UI control to collect project settings when importing a Blaze project. */
public final class BlazeEditProjectViewControl {
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/actions/BuildFileModifierTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/actions/BuildFileModifierTest.java
new file mode 100644
index 0000000..311cfdf
--- /dev/null
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/actions/BuildFileModifierTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017 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.actions;
+
+import com.google.idea.blaze.base.buildmodifier.BuildFileModifier;
+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.Kind;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.scope.BlazeContext;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Integration tests for {@link BuildFileModifier}. */
+@RunWith(JUnit4.class)
+public class BuildFileModifierTest extends BuildFileIntegrationTestCase {
+
+ @Test
+ public void testAddNewTarget() {
+ BuildFile buildFile =
+ createBuildFile(new WorkspacePath("BUILD"), "java_library(name = 'existing')", "");
+ BuildFileModifier.getInstance()
+ .addRule(getProject(), new BlazeContext(), new Label("//:new_target"), Kind.JAVA_TEST);
+ assertFileContents(
+ buildFile,
+ "java_library(name = 'existing')",
+ "java_test(",
+ " name = \"new_target\"",
+ ")");
+ }
+}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionSymbolCompletionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionSymbolCompletionTest.java
index 44f3cb9..7a297ac 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionSymbolCompletionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionSymbolCompletionTest.java
@@ -96,4 +96,18 @@
assertThat(editorTest.completeIfUnique()).isTrue();
assertFileContents(file, "load(':skylark.bzl', 'function')");
}
+
+ @Test
+ public void testPrivateSymbolsNotAutocompleted() {
+ workspace.createFile(
+ new WorkspacePath("skylark.bzl"),
+ "_local = 1",
+ "GLOBAL_VAR = 2",
+ "def _local_fn():stmt",
+ "def global_fn():stmt");
+ createAndSetCaret(new WorkspacePath("BUILD"), "load(':skylark.bzl', '<caret>')");
+
+ String[] options = editorTest.getCompletionItemsAsStrings();
+ assertThat(options).asList().containsExactly("'GLOBAL_VAR'", "'global_fn'");
+ }
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/quickfix/DeprecatedLoadQuickFixTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/quickfix/DeprecatedLoadQuickFixTest.java
new file mode 100644
index 0000000..549334f
--- /dev/null
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/quickfix/DeprecatedLoadQuickFixTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2017 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.quickfix;
+
+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.lang.buildfile.psi.StringLiteral;
+import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.ProblemHighlightType;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.psi.PsiElement;
+import com.intellij.testFramework.MockProblemDescriptor;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Integration tests for {@link DeprecatedLoadQuickFix}. */
+@RunWith(JUnit4.class)
+public class DeprecatedLoadQuickFixTest extends BuildFileIntegrationTestCase {
+
+ @Test
+ public void testParentDirectoryHasNoBuildFile() {
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "load('/java/com/google/subdir/build_defs.bzl', 'symbol')");
+
+ StringLiteral string = PsiUtils.findFirstChildOfClassRecursive(file, StringLiteral.class);
+ applyQuickFix(string);
+
+ assertThat(string.getStringContents()).isEqualTo("//java/com/google:subdir/build_defs.bzl");
+ }
+
+ @Test
+ public void testBlazePackageIsParentDirectory() {
+ workspace.createPsiFile(new WorkspacePath("foo/bar/BUILD"));
+ workspace.createPsiFile(new WorkspacePath("foo/bar/build_defs.bzl"));
+
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "load('/foo/bar/build_defs.bzl', 'symbol')");
+
+ StringLiteral string = PsiUtils.findFirstChildOfClassRecursive(file, StringLiteral.class);
+ applyQuickFix(string);
+
+ assertThat(string.getStringContents()).isEqualTo("//foo/bar:build_defs.bzl");
+ }
+
+ @Test
+ public void testNormalLoadStatementUntouched() {
+ workspace.createPsiFile(new WorkspacePath("foo/bar/BUILD"));
+ workspace.createPsiFile(new WorkspacePath("foo/bar/build_defs.bzl"));
+
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "load('//foo/bar:build_defs.bzl', 'symbol')");
+
+ StringLiteral string = PsiUtils.findFirstChildOfClassRecursive(file, StringLiteral.class);
+ String prevString = string.getStringContents();
+ applyQuickFix(string);
+ assertThat(string.getStringContents()).isEqualTo(prevString);
+ }
+
+ @Test
+ public void testRelativeLoadStatementUntouched() {
+ workspace.createPsiFile(new WorkspacePath("foo/bar/build_defs.bzl"));
+ BuildFile file =
+ createBuildFile(new WorkspacePath("foo/bar/BUILD"), "load(':build_defs.bzl', 'symbol')");
+
+ StringLiteral string = PsiUtils.findFirstChildOfClassRecursive(file, StringLiteral.class);
+ String prevString = string.getStringContents();
+ applyQuickFix(string);
+ assertThat(string.getStringContents()).isEqualTo(prevString);
+ }
+
+ private void applyQuickFix(StringLiteral string) {
+ WriteCommandAction.runWriteCommandAction(
+ getProject(),
+ () -> DeprecatedLoadQuickFix.INSTANCE.applyFix(getProject(), descriptorForPsi(string)));
+ }
+
+ private static ProblemDescriptor descriptorForPsi(PsiElement psi) {
+ return new MockProblemDescriptor(
+ psi, "mock", ProblemHighlightType.LIKE_DEPRECATED, DeprecatedLoadQuickFix.INSTANCE);
+ }
+}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LoadedSkylarkExtensionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LoadedSkylarkExtensionTest.java
index b43f778..5cf33ab 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LoadedSkylarkExtensionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LoadedSkylarkExtensionTest.java
@@ -17,14 +17,26 @@
import static com.google.common.truth.Truth.assertThat;
+import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
+import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpec;
+import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpecProvider;
+import com.google.idea.blaze.base.lang.buildfile.language.semantics.RuleDefinition;
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.FunctionStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.LoadStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.LoadedSymbol;
+import com.google.idea.blaze.base.lang.buildfile.psi.ReferenceExpression;
+import com.google.idea.blaze.base.lang.buildfile.psi.TargetExpression;
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.openapi.project.Project;
+import com.intellij.psi.PsiReference;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+import javax.annotation.Nullable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -67,7 +79,7 @@
// BuildFile buildFile = createBuildFile(
// "java/com/google/tools/BUILD",
// "load(",
- // "\"//java/com/google/build_defs.bzl\",",
+ // "\"/java/com/google/build_defs.bzl\",",
// "\"function\"",
// ")");
//
@@ -119,6 +131,71 @@
}
@Test
+ public void testLoadedSymbolReference() {
+ BuildFile extFile =
+ createBuildFile(new WorkspacePath("java/com/google/tools/build_defs.bzl"), "CONSTANT = 1");
+
+ BuildFile buildFile =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "load(",
+ "\"//java/com/google/tools:build_defs.bzl\",",
+ "\"CONSTANT\"",
+ ")",
+ "NEW_CONSTANT = CONSTANT");
+
+ TargetExpression target =
+ PsiUtils.findFirstChildOfClassRecursive(extFile, TargetExpression.class);
+ ReferenceExpression ref =
+ PsiUtils.findFirstChildOfClassRecursive(buildFile, ReferenceExpression.class);
+ LoadedSymbol loadElement =
+ PsiUtils.findFirstChildOfClassRecursive(buildFile, LoadedSymbol.class);
+
+ assertThat(target).isNotNull();
+ assertThat(ref.getReferencedElement()).isEqualTo(target);
+ assertThat(loadElement.getImport().getReferencedElement()).isEqualTo(target);
+
+ assertThat(
+ Arrays.stream(FindUsages.findAllReferences(target))
+ .map(PsiReference::getElement)
+ .collect(Collectors.toList()))
+ .containsExactly(ref, loadElement.getImport());
+ }
+
+ @Test
+ public void testOverridenBuiltInSymbolReference() {
+ setBuiltInRuleNames("java_library");
+ BuildFile extFile =
+ createBuildFile(
+ new WorkspacePath("java/com/google/tools/build_defs.bzl"), "java_library = rule()");
+
+ BuildFile buildFile =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "load(",
+ "\"//java/com/google/tools:build_defs.bzl\",",
+ "\"java_library\"",
+ ")",
+ "java_library(name = 'name')");
+
+ TargetExpression target =
+ PsiUtils.findFirstChildOfClassRecursive(extFile, TargetExpression.class);
+ FuncallExpression funcall = buildFile.firstChildOfClass(FuncallExpression.class);
+ LoadedSymbol loadElement =
+ PsiUtils.findFirstChildOfClassRecursive(buildFile, LoadedSymbol.class);
+
+ assertThat(target).isNotNull();
+ assertThat(funcall.getReferencedElement()).isEqualTo(target);
+ assertThat(loadElement.getImport().getReferencedElement()).isEqualTo(target);
+
+ assertThat(
+ Arrays.stream(FindUsages.findAllReferences(target))
+ .map(PsiReference::getElement)
+ .collect(Collectors.toList()))
+ .containsExactly(funcall, loadElement.getImport());
+ }
+
+ @Test
public void testFuncallReference() {
BuildFile extFile =
createBuildFile(
@@ -181,4 +258,30 @@
assertThat(function).isNotNull();
assertThat(funcall.getReferencedElement()).isEqualTo(function);
}
+
+ private void setBuiltInRuleNames(String... ruleNames) {
+ ImmutableMap.Builder<String, RuleDefinition> rules = ImmutableMap.builder();
+ for (String name : ruleNames) {
+ rules.put(name, new RuleDefinition(name, ImmutableMap.of(), null));
+ }
+ MockBuildLanguageSpecProvider specProvider = new MockBuildLanguageSpecProvider();
+ specProvider.setRules(rules.build());
+ registerApplicationService(BuildLanguageSpecProvider.class, specProvider);
+ specProvider.setRules(rules.build());
+ }
+
+ private static class MockBuildLanguageSpecProvider implements BuildLanguageSpecProvider {
+
+ BuildLanguageSpec languageSpec = new BuildLanguageSpec(ImmutableMap.of());
+
+ void setRules(ImmutableMap<String, RuleDefinition> rules) {
+ languageSpec = new BuildLanguageSpec(rules);
+ }
+
+ @Nullable
+ @Override
+ public BuildLanguageSpec getLanguageSpec(Project project) {
+ return languageSpec;
+ }
+ }
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/LoadStatementAnnotatorTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/LoadStatementAnnotatorTest.java
new file mode 100644
index 0000000..9af84e7
--- /dev/null
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/LoadStatementAnnotatorTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2017 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.validation;
+
+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.BuildElement;
+import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
+import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl;
+import com.intellij.lang.annotation.Annotation;
+import com.intellij.lang.annotation.AnnotationHolder;
+import com.intellij.lang.annotation.AnnotationSession;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.psi.PsiFile;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link LoadStatementAnnotator}. */
+@RunWith(JUnit4.class)
+public class LoadStatementAnnotatorTest extends BuildFileIntegrationTestCase {
+
+ @Test
+ public void testNoWarningsInNormalLoad() {
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "load('//tools/ide/build_test.bzl', 'build_test')",
+ "load(':local_file.bzl', 'symbol')");
+ assertNoAnnotations(file);
+ }
+
+ @Test
+ public void testNoWarningsWhenTyping() {
+ BuildFile file = createBuildFile(new WorkspacePath("java/com/google/BUILD"), "load('/')");
+ assertNoAnnotations(file);
+ }
+
+ @Test
+ public void testWarningForDeprecatedFormat() {
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "load('/tools/ide/build_test.bzl', 'build_test')");
+ assertHasAnnotation(
+ file,
+ "Deprecated load syntax; loaded Skylark module should by in label format.",
+ HighlightSeverity.WARNING);
+ }
+
+ @Test
+ public void testErrorForUnrecognizedFormat() {
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"), "load('not a skylark label', 'symbol')");
+ assertHasAnnotation(
+ file, "Invalid load syntax: missing Skylark module.", HighlightSeverity.ERROR);
+ }
+
+ @Test
+ public void testErrorForPrivateSymbols() {
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"), "load(':skylark.bzl', '_local_symbol')");
+ assertHasAnnotation(
+ file, "Symbol '_local_symbol' is private and cannot be imported.", HighlightSeverity.ERROR);
+ }
+
+ private void assertNoAnnotations(BuildFile file) {
+ assertThat(validateFile(file)).isEmpty();
+ }
+
+ private void assertHasAnnotation(BuildFile file, String message, HighlightSeverity type) {
+ assertThat(
+ validateFile(file)
+ .stream()
+ .filter(ann -> ann.getSeverity().equals(type))
+ .map(Annotation::getMessage)
+ .collect(Collectors.toList()))
+ .contains(message);
+ }
+
+ private List<Annotation> validateFile(BuildFile file) {
+ LoadStatementAnnotator annotator = createAnnotator(file);
+ PsiUtils.findAllChildrenOfClassRecursive(file, BuildElement.class)
+ .forEach(element -> element.accept(annotator));
+ return annotationHolder;
+ }
+
+ private LoadStatementAnnotator createAnnotator(PsiFile file) {
+ annotationHolder = new AnnotationHolderImpl(new AnnotationSession(file));
+ return new LoadStatementAnnotator() {
+ @Override
+ protected AnnotationHolder getHolder() {
+ return annotationHolder;
+ }
+ };
+ }
+
+ private AnnotationHolderImpl annotationHolder = null;
+}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/run/TestTargetHeuristicTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/run/TestTargetHeuristicTest.java
index 6cd2d7c..c68a696 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/run/TestTargetHeuristicTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/run/TestTargetHeuristicTest.java
@@ -19,12 +19,19 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.BlazeIntegrationTestCase;
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.ideinfo.TestIdeInfo;
import com.google.idea.blaze.base.ideinfo.TestIdeInfo.TestSize;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataManager;
import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import java.io.File;
import java.util.Collection;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -33,9 +40,16 @@
@RunWith(JUnit4.class)
public class TestTargetHeuristicTest extends BlazeIntegrationTestCase {
+ @Before
+ public final void doSetup() {
+ BlazeProjectData blazeProjectData = MockBlazeProjectDataBuilder.builder(workspaceRoot).build();
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(blazeProjectData));
+ }
+
@Test
- public void testTestSizeMatched() throws Exception {
- File source = new File("java/com/foo/FooTest.java");
+ public void testTestSizeMatched() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
Collection<TargetIdeInfo> targets =
ImmutableList.of(
TargetIdeInfo.builder()
@@ -49,24 +63,46 @@
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.SMALL))
.build());
Label match =
- TestTargetHeuristic.chooseTestTargetForSourceFile(source, targets, TestSize.SMALL);
+ TestTargetHeuristic.chooseTestTargetForSourceFile(
+ getProject(), source, targets, TestSize.SMALL);
assertThat(match).isEqualTo(new Label("//foo:test2"));
}
@Test
- public void testTargetNameMatched() throws Exception {
- File source = new File("java/com/foo/FooTest.java");
+ public void testTargetSourcesMatched() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
+ Collection<TargetIdeInfo> targets =
+ ImmutableList.of(
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test1")
+ .setKind("java_test")
+ .addSource(sourceRoot("java/com/bar/OtherTest.java"))
+ .build(),
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test2")
+ .setKind("java_test")
+ .addSource(sourceRoot("java/com/foo/FooTest.java"))
+ .build());
+ Label match =
+ TestTargetHeuristic.chooseTestTargetForSourceFile(getProject(), source, targets, null);
+ assertThat(match).isEqualTo(new Label("//foo:test2"));
+ }
+
+ @Test
+ public void testTargetNameMatched() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
Collection<TargetIdeInfo> targets =
ImmutableList.of(
TargetIdeInfo.builder().setLabel("//foo:FirstTest").setKind("java_test").build(),
TargetIdeInfo.builder().setLabel("//foo:FooTest").setKind("java_test").build());
- Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(source, targets, null);
+ Label match =
+ TestTargetHeuristic.chooseTestTargetForSourceFile(getProject(), source, targets, null);
assertThat(match).isEqualTo(new Label("//foo:FooTest"));
}
@Test
- public void testNoMatchFallBackToFirstTarget() throws Exception {
- File source = new File("java/com/foo/FooTest.java");
+ public void testNoMatchFallBackToFirstTarget() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
ImmutableList<TargetIdeInfo> targets =
ImmutableList.of(
TargetIdeInfo.builder()
@@ -80,13 +116,14 @@
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.SMALL))
.build());
Label match =
- TestTargetHeuristic.chooseTestTargetForSourceFile(source, targets, TestSize.LARGE);
+ TestTargetHeuristic.chooseTestTargetForSourceFile(
+ getProject(), source, targets, TestSize.LARGE);
assertThat(match).isEqualTo(new Label("//bar:BarTest"));
}
@Test
- public void testTargetNameCheckedBeforeTestSize() throws Exception {
- File source = new File("java/com/foo/FooTest.java");
+ public void testTargetNameCheckedBeforeTestSize() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
ImmutableList<TargetIdeInfo> targets =
ImmutableList.of(
TargetIdeInfo.builder()
@@ -100,7 +137,35 @@
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.MEDIUM))
.build());
Label match =
- TestTargetHeuristic.chooseTestTargetForSourceFile(source, targets, TestSize.SMALL);
+ TestTargetHeuristic.chooseTestTargetForSourceFile(
+ getProject(), source, targets, TestSize.SMALL);
assertThat(match).isEqualTo(new Label("//foo:FooTest"));
}
+
+ @Test
+ public void testTargetSourcesCheckedBeforeTestSize() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
+ Collection<TargetIdeInfo> targets =
+ ImmutableList.of(
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test1")
+ .setKind("java_test")
+ .setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.SMALL))
+ .addSource(sourceRoot("java/com/bar/OtherTest.java"))
+ .build(),
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test2")
+ .setKind("java_test")
+ .setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.MEDIUM))
+ .addSource(sourceRoot("java/com/foo/FooTest.java"))
+ .build());
+ Label match =
+ TestTargetHeuristic.chooseTestTargetForSourceFile(
+ getProject(), source, targets, TestSize.SMALL);
+ assertThat(match).isEqualTo(new Label("//foo:test2"));
+ }
+
+ private static ArtifactLocation sourceRoot(String relativePath) {
+ return ArtifactLocation.builder().setRelativePath(relativePath).setIsSource(true).build();
+ }
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/run/producer/AllInPackageBlazeConfigurationProducerTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/run/producer/AllInPackageBlazeConfigurationProducerTest.java
new file mode 100644
index 0000000..7063c58
--- /dev/null
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/run/producer/AllInPackageBlazeConfigurationProducerTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2017 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.run.producer;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.model.primitives.TargetExpression;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.producers.AllInPackageBlazeConfigurationProducer;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
+import com.intellij.psi.PsiDirectory;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Integration tests for {@link AllInPackageBlazeConfigurationProducer}. */
+@RunWith(JUnit4.class)
+public class AllInPackageBlazeConfigurationProducerTest
+ extends BlazeRunConfigurationProducerTestCase {
+
+ @Test
+ public void testProducedFromPsiDirectory() {
+ PsiDirectory directory =
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+ workspace.createPsiFile(
+ new WorkspacePath("java/com/google/test/BUILD"), "java_test(name='unit_tests'");
+
+ ConfigurationContext context = createContextFromPsi(directory);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(AllInPackageBlazeConfigurationProducer.class)).isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test/...:all"));
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+
+ @Test
+ public void testDirectoryWithoutBlazePackageChildIsIgnored() {
+ PsiDirectory directory =
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+
+ ConfigurationContext context = createContextFromPsi(directory);
+
+ AllInPackageBlazeConfigurationProducer producer = new AllInPackageBlazeConfigurationProducer();
+ assertThat(producer.createConfigurationFromContext(context)).isNull();
+
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test/child_dir"));
+ workspace.createPsiFile(new WorkspacePath("java/com/google/test/child_dir/BUILD"));
+
+ assertThat(producer.createConfigurationFromContext(context)).isNotNull();
+ }
+}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/run/producer/BlazeBuildFileRunConfigurationProducerTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/run/producer/BlazeBuildFileRunConfigurationProducerTest.java
new file mode 100644
index 0000000..dcf3e6b
--- /dev/null
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/run/producer/BlazeBuildFileRunConfigurationProducerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017 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.run.producer;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+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.model.primitives.TargetExpression;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.producers.BlazeBuildFileRunConfigurationProducer;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
+import com.intellij.psi.PsiFile;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Integration tests for {@link BlazeBuildFileRunConfigurationProducer}. */
+@RunWith(JUnit4.class)
+public class BlazeBuildFileRunConfigurationProducerTest
+ extends BlazeRunConfigurationProducerTestCase {
+
+ @Test
+ public void testProducedFromFuncallExpression() {
+ PsiFile buildFile =
+ workspace.createPsiFile(
+ new WorkspacePath("java/com/google/test/BUILD"), "java_test(name='unit_tests'");
+
+ FuncallExpression target =
+ PsiUtils.findFirstChildOfClassRecursive(buildFile, FuncallExpression.class);
+ assertThat(target).isNotNull();
+
+ ConfigurationContext context = createContextFromPsi(target);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(BlazeBuildFileRunConfigurationProducer.class)).isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:unit_tests"));
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+
+ @Test
+ public void testProducedWhenInsideFuncallExpression() {
+ PsiFile buildFile =
+ workspace.createPsiFile(
+ new WorkspacePath("java/com/google/test/BUILD"), "java_test(name='unit_tests'");
+
+ StringLiteral nameString =
+ PsiUtils.findFirstChildOfClassRecursive(buildFile, StringLiteral.class);
+ assertThat(nameString).isNotNull();
+
+ ConfigurationContext context = createContextFromPsi(nameString);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(BlazeBuildFileRunConfigurationProducer.class)).isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:unit_tests"));
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/actions/BlazeBuildServiceTest.java b/base/tests/unittests/com/google/idea/blaze/base/actions/BlazeBuildServiceTest.java
index cce3237..607aa15 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/actions/BlazeBuildServiceTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/actions/BlazeBuildServiceTest.java
@@ -59,7 +59,7 @@
@Override
protected void initTest(Container applicationServices, Container projectServices) {
- BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager(project);
+ BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager();
importSettingsManager.setImportSettings(
new BlazeImportSettings("", "", "", "", "", Blaze.BuildSystem.Blaze));
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
diff --git a/base/tests/unittests/com/google/idea/blaze/base/command/BlazeCommandTest.java b/base/tests/unittests/com/google/idea/blaze/base/command/BlazeCommandTest.java
index 64b6894..d50882b 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/command/BlazeCommandTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/command/BlazeCommandTest.java
@@ -21,7 +21,6 @@
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
-import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.settings.BlazeUserSettings;
import com.google.idea.common.experiments.ExperimentService;
import com.google.idea.common.experiments.MockExperimentService;
@@ -47,7 +46,7 @@
@Test
public void addedFlagsShouldGoAtStart() {
List<String> flagsCommand =
- BlazeCommand.builder(BuildSystem.Blaze, BlazeCommandName.RUN)
+ BlazeCommand.builder("/usr/bin/blaze", BlazeCommandName.RUN)
.addTargets(new Label("//a:b"))
.addBlazeFlags("--flag1", "--flag2")
.addExeFlags("--exeFlag1", "--exeFlag2")
@@ -60,7 +59,7 @@
@Test
public void targetsShouldGoAfterBlazeFlagsAndDoubleHyphen() {
List<String> command =
- BlazeCommand.builder(BuildSystem.Blaze, BlazeCommandName.RUN)
+ BlazeCommand.builder("/usr/bin/blaze", BlazeCommandName.RUN)
.addTargets(new Label("//a:b"), new Label("//c:d"))
.addBlazeFlags("--flag1", "--flag2")
.addExeFlags("--exeFlag1", "--exeFlag2")
@@ -75,7 +74,7 @@
@Test
public void exeFlagsShouldGoLast() {
List<String> command =
- BlazeCommand.builder(BuildSystem.Blaze, BlazeCommandName.RUN)
+ BlazeCommand.builder("/usr/bin/blaze", BlazeCommandName.RUN)
.addTargets(new Label("//a:b"), new Label("//c:d"))
.addBlazeFlags("--flag1", "--flag2")
.addExeFlags("--exeFlag1", "--exeFlag2")
@@ -88,7 +87,7 @@
@Test
public void maintainUserOrderingOfTargets() {
List<String> command =
- BlazeCommand.builder(BuildSystem.Blaze, BlazeCommandName.RUN)
+ BlazeCommand.builder("/usr/bin/blaze", BlazeCommandName.RUN)
.addTargets(
new Label("//a:b"), TargetExpression.fromString("-//e:f"), new Label("//c:d"))
.addBlazeFlags("--flag1", "--flag2")
@@ -116,7 +115,7 @@
@Test
public void binaryAndCommandShouldComeFirst() {
List<String> command =
- BlazeCommand.builder(BuildSystem.Blaze, BlazeCommandName.BUILD)
+ BlazeCommand.builder("/usr/bin/blaze", BlazeCommandName.BUILD)
.addBlazeFlags("--flag")
.addExeFlags("--exeFlag")
.build()
diff --git a/base/tests/unittests/com/google/idea/blaze/base/model/blaze/deepequalstester/DeepEqualsTesterUtil.java b/base/tests/unittests/com/google/idea/blaze/base/model/blaze/deepequalstester/DeepEqualsTesterUtil.java
index 2ef9472..2f2457b 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/model/blaze/deepequalstester/DeepEqualsTesterUtil.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/model/blaze/deepequalstester/DeepEqualsTesterUtil.java
@@ -23,8 +23,8 @@
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.List;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Utilities for deep equals testing. */
@VisibleForTesting
diff --git a/base/tests/unittests/com/google/idea/blaze/base/projectview/parser/ProjectViewParserTest.java b/base/tests/unittests/com/google/idea/blaze/base/projectview/parser/ProjectViewParserTest.java
index 08fea57..52ed8cf 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/projectview/parser/ProjectViewParserTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/projectview/parser/ProjectViewParserTest.java
@@ -48,8 +48,8 @@
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationTest.java
index 2f1cac6..989cb80 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationTest.java
@@ -54,8 +54,7 @@
super.initTest(applicationServices, projectServices);
applicationServices.register(UISettings.class, new UISettings());
- projectServices.register(
- BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
+ projectServices.register(BlazeImportSettingsManager.class, new BlazeImportSettingsManager());
BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
applicationServices.register(ExperimentService.class, new MockExperimentService());
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/RuleNameHeuristicTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/RuleNameHeuristicTest.java
index 2923947..f7a0857 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/run/RuleNameHeuristicTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/RuleNameHeuristicTest.java
@@ -46,7 +46,7 @@
File source = new File("java/com/foo/FooTest.java");
TargetIdeInfo target =
TargetIdeInfo.builder().setLabel("//foo:FooTest").setKind("java_test").build();
- assertThat(new TargetNameHeuristic().matchesSource(target, source, null)).isTrue();
+ assertThat(new TargetNameHeuristic().matchesSource(project, target, source, null)).isTrue();
}
@Test
@@ -54,7 +54,7 @@
File source = new File("java/com/foo/FooTest.java");
TargetIdeInfo target =
TargetIdeInfo.builder().setLabel("//foo:foo/FooTest").setKind("java_test").build();
- assertThat(new TargetNameHeuristic().matchesSource(target, source, null)).isTrue();
+ assertThat(new TargetNameHeuristic().matchesSource(project, target, source, null)).isTrue();
}
@Test
@@ -62,7 +62,7 @@
File source = new File("java/com/foo/BarFooTest.java");
TargetIdeInfo target =
TargetIdeInfo.builder().setLabel("//foo:FooTest").setKind("java_test").build();
- assertThat(new TargetNameHeuristic().matchesSource(target, source, null)).isFalse();
+ assertThat(new TargetNameHeuristic().matchesSource(project, target, source, null)).isFalse();
}
@Test
@@ -70,7 +70,7 @@
File source = new File("java/com/foo/FooTest.java");
TargetIdeInfo target =
TargetIdeInfo.builder().setLabel("//foo:bar/FooTest").setKind("java_test").build();
- assertThat(new TargetNameHeuristic().matchesSource(target, source, null)).isFalse();
+ assertThat(new TargetNameHeuristic().matchesSource(project, target, source, null)).isFalse();
}
@Test
@@ -78,7 +78,7 @@
File source = new File("java/com/foo/FooTest.java");
TargetIdeInfo target =
TargetIdeInfo.builder().setLabel("//foo:ForTest").setKind("java_test").build();
- assertThat(new TargetNameHeuristic().matchesSource(target, source, null)).isFalse();
+ assertThat(new TargetNameHeuristic().matchesSource(project, target, source, null)).isFalse();
}
@Test
@@ -88,7 +88,7 @@
ImmutableList.of(
TargetIdeInfo.builder().setLabel("//foo:FirstTest").setKind("java_test").build(),
TargetIdeInfo.builder().setLabel("//bar:OtherTest").setKind("java_test").build());
- Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(source, targets, null);
+ Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(project, source, targets, null);
assertThat(match).isEqualTo(new Label("//foo:FirstTest"));
}
@@ -99,7 +99,7 @@
ImmutableList.of(
TargetIdeInfo.builder().setLabel("//bar:FirstTest").setKind("java_test").build(),
TargetIdeInfo.builder().setLabel("//foo:FooTest").setKind("java_test").build());
- Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(source, targets, null);
+ Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(project, source, targets, null);
assertThat(match).isEqualTo(new Label("//foo:FooTest"));
}
@@ -111,7 +111,7 @@
TargetIdeInfo.builder().setLabel("//bar:OtherTest").setKind("java_test").build(),
TargetIdeInfo.builder().setLabel("//foo:FooTest").setKind("java_test").build(),
TargetIdeInfo.builder().setLabel("//bar/foo:FooTest").setKind("java_test").build());
- Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(source, targets, null);
+ Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(project, source, targets, null);
assertThat(match).isEqualTo(new Label("//foo:FooTest"));
}
}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/TestSizeHeuristicTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/TestSizeHeuristicTest.java
index 99ce084..34a41d4 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/run/TestSizeHeuristicTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/TestSizeHeuristicTest.java
@@ -51,7 +51,8 @@
.setKind("java_test")
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.MEDIUM))
.build();
- assertThat(new TestSizeHeuristic().matchesSource(target, source, TestSize.MEDIUM)).isTrue();
+ assertThat(new TestSizeHeuristic().matchesSource(project, target, source, TestSize.MEDIUM))
+ .isTrue();
}
@Test
@@ -63,7 +64,8 @@
.setKind("java_test")
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.MEDIUM))
.build();
- assertThat(new TestSizeHeuristic().matchesSource(target, source, TestSize.SMALL)).isFalse();
+ assertThat(new TestSizeHeuristic().matchesSource(project, target, source, TestSize.SMALL))
+ .isFalse();
}
@Test
@@ -75,7 +77,7 @@
.setKind("java_test")
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.SMALL))
.build();
- assertThat(new TestSizeHeuristic().matchesSource(target, source, null)).isTrue();
+ assertThat(new TestSizeHeuristic().matchesSource(project, target, source, null)).isTrue();
target =
TargetIdeInfo.builder()
@@ -83,7 +85,7 @@
.setKind("java_test")
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.MEDIUM))
.build();
- assertThat(new TestSizeHeuristic().matchesSource(target, source, null)).isFalse();
+ assertThat(new TestSizeHeuristic().matchesSource(project, target, source, null)).isFalse();
}
@Test
@@ -106,7 +108,8 @@
.setKind("java_test")
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.ENORMOUS))
.build());
- Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(source, rules, TestSize.SMALL);
+ Label match =
+ TestTargetHeuristic.chooseTestTargetForSourceFile(project, source, rules, TestSize.SMALL);
assertThat(match).isEqualTo(new Label("//foo:test1"));
}
@@ -125,7 +128,8 @@
.setKind("java_test")
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.SMALL))
.build());
- Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(source, rules, TestSize.SMALL);
+ Label match =
+ TestTargetHeuristic.chooseTestTargetForSourceFile(project, source, rules, TestSize.SMALL);
assertThat(match).isEqualTo(new Label("//foo:test2"));
}
@@ -149,7 +153,8 @@
.setKind("java_test")
.setTestInfo(TestIdeInfo.builder().setTestSize(TestSize.SMALL))
.build());
- Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(source, rules, TestSize.SMALL);
+ Label match =
+ TestTargetHeuristic.chooseTestTargetForSourceFile(project, source, rules, TestSize.SMALL);
assertThat(match).isEqualTo(new Label("//foo:test2"));
}
}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/TestTargetSourcesHeuristicTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/TestTargetSourcesHeuristicTest.java
new file mode 100644
index 0000000..37ec7ae
--- /dev/null
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/TestTargetSourcesHeuristicTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017 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.run;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.BlazeTestCase;
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataManager;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.intellij.openapi.extensions.impl.ExtensionPointImpl;
+import java.io.File;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link TestTargetSourcesHeuristic}. */
+@RunWith(JUnit4.class)
+public class TestTargetSourcesHeuristicTest extends BlazeTestCase {
+
+ private final WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File("/"));
+
+ @Override
+ protected void initTest(Container applicationServices, Container projectServices) {
+ super.initTest(applicationServices, projectServices);
+
+ BlazeProjectData blazeProjectData = MockBlazeProjectDataBuilder.builder(workspaceRoot).build();
+ projectServices.register(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(blazeProjectData));
+
+ ExtensionPointImpl<TestTargetHeuristic> ep =
+ registerExtensionPoint(TestTargetHeuristic.EP_NAME, TestTargetHeuristic.class);
+ ep.registerExtension(new TestTargetSourcesHeuristic());
+ }
+
+ @Test
+ public void testPredicateNoSources() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
+ TargetIdeInfo target =
+ TargetIdeInfo.builder().setLabel("//foo:test").setKind("java_test").build();
+ assertThat(new TestTargetSourcesHeuristic().matchesSource(project, target, source, null))
+ .isFalse();
+ }
+
+ @Test
+ public void testPredicateNoMatchingSource() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
+ TargetIdeInfo target =
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test")
+ .setKind("java_test")
+ .addSource(sourceRoot("java/com/bar/OtherTest.java"))
+ .build();
+ assertThat(new TestTargetSourcesHeuristic().matchesSource(project, target, source, null))
+ .isFalse();
+ }
+
+ @Test
+ public void testPredicateMatchingSource() {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
+ TargetIdeInfo target =
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test")
+ .setKind("java_test")
+ .addSource(sourceRoot("java/com/bar/OtherTest.java"))
+ .addSource(sourceRoot("java/com/foo/FooTest.java"))
+ .build();
+ assertThat(new TestTargetSourcesHeuristic().matchesSource(project, target, source, null))
+ .isTrue();
+ }
+
+ @Test
+ public void testFilterNoMatchesFallBackToFirstRule() throws Exception {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
+ ImmutableList<TargetIdeInfo> rules =
+ ImmutableList.of(
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test1")
+ .setKind("java_test")
+ .addSource(sourceRoot("java/com/bar/OtherTest.java"))
+ .build(),
+ TargetIdeInfo.builder().setLabel("//foo:test2").setKind("java_test").build());
+ Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(project, source, rules, null);
+ assertThat(match).isEqualTo(new Label("//foo:test1"));
+ }
+
+ @Test
+ public void testFilterOneMatch() throws Exception {
+ File source = workspaceRoot.fileForPath(new WorkspacePath("java/com/foo/FooTest.java"));
+ ImmutableList<TargetIdeInfo> rules =
+ ImmutableList.of(
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test1")
+ .setKind("java_test")
+ .addSource(sourceRoot("java/com/bar/OtherTest.java"))
+ .build(),
+ TargetIdeInfo.builder()
+ .setLabel("//foo:test2")
+ .setKind("java_test")
+ .addSource(sourceRoot("java/com/foo/FooTest.java"))
+ .build());
+ Label match = TestTargetHeuristic.chooseTestTargetForSourceFile(project, source, rules, null);
+ assertThat(match).isEqualTo(new Label("//foo:test2"));
+ }
+
+ private static ArtifactLocation sourceRoot(String relativePath) {
+ return ArtifactLocation.builder().setRelativePath(relativePath).setIsSource(true).build();
+ }
+}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/smrunner/BlazeXmlSchemaTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/smrunner/BlazeXmlSchemaTest.java
index 5c7dc35..2ed69f5 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/run/smrunner/BlazeXmlSchemaTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/smrunner/BlazeXmlSchemaTest.java
@@ -24,6 +24,7 @@
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -68,4 +69,51 @@
TestSuite parsed = BlazeXmlSchema.parse(stream);
assertThat(parsed).isNotNull();
}
+
+ @Test
+ public void testMergeShardedTests() {
+ TestSuite shard1 =
+ parseXml(
+ "<?xml version='1.0' encoding='UTF-8'?>",
+ "<testsuites>",
+ " <testsuite name='com.google.ConfigTest' time='10' tests='2' failures='1'>",
+ " <testcase name='testCase1' time='2.1' status='run' result='completed'/>",
+ " <testcase name='testCase2' time='7.9' status='run' result='completed'>",
+ " <failure message='failed'/>",
+ " </testcase>",
+ " </testsuite>",
+ "</testsuites>");
+ TestSuite shard2 =
+ parseXml(
+ "<?xml version='1.0' encoding='UTF-8'?>",
+ "<testsuites>",
+ " <testsuite name='com.google.ConfigTest' time='5' tests='2' failures='1'>",
+ " <testcase name='testCase3' time='1' status='run' result='completed'/>",
+ " <testcase name='testCase4' time='4' status='run' result='completed'>",
+ " <failure message='failed'/>",
+ " </testcase>",
+ " </testsuite>",
+ "</testsuites>");
+ TestSuite mergedOuter = BlazeXmlSchema.mergeSuites(ImmutableList.of(shard1, shard2));
+ assertThat(mergedOuter.testSuites).hasSize(1);
+ TestSuite mergedInner = mergedOuter.testSuites.get(0).testSuites.get(0);
+ assertThat(mergedInner.name).isEqualTo("com.google.ConfigTest");
+ assertThat(mergedInner.time).isEqualTo(15d);
+ assertThat(mergedInner.tests).isEqualTo(4);
+ assertThat(mergedInner.failures).isEqualTo(2);
+ assertThat(mergedInner.testCases).hasSize(4);
+ assertThat(
+ mergedInner
+ .testCases
+ .stream()
+ .map(testCase -> testCase.name)
+ .collect(Collectors.toList()))
+ .containsExactly("testCase1", "testCase2", "testCase3", "testCase4");
+ }
+
+ private static TestSuite parseXml(String... lines) {
+ InputStream stream =
+ new ByteArrayInputStream(Joiner.on('\n').join(lines).getBytes(StandardCharsets.UTF_8));
+ return BlazeXmlSchema.parse(stream);
+ }
}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonStateTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonStateTest.java
index 5598b49..e94bedf 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonStateTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonStateTest.java
@@ -47,8 +47,7 @@
super.initTest(applicationServices, projectServices);
applicationServices.register(UISettings.class, new UISettings());
- projectServices.register(
- BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
+ projectServices.register(BlazeImportSettingsManager.class, new BlazeImportSettingsManager());
BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
registerExtensionPoint(DistributedExecutorSupport.EP_NAME, DistributedExecutorSupport.class);
diff --git a/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderTest.java b/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderTest.java
index a7c7816..eb02cba 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderTest.java
@@ -17,18 +17,10 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
-import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
-import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import java.io.File;
-import java.util.List;
-import java.util.Set;
-import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -40,77 +32,6 @@
private static final String EXECUTION_ROOT = "/path/to/_blaze_user/1234bf129e/root";
private static final String OUTPUT_BASE = "/path/to/_blaze_user/1234bf129e";
- static class MockFileAttributeProvider extends FileAttributeProvider {
- final Set<File> files = Sets.newHashSet();
-
- void addFiles(@NotNull File... files) {
- this.files.addAll(Lists.newArrayList(files));
- }
-
- @Override
- public boolean exists(@NotNull File file) {
- return files.contains(file);
- }
- }
-
- private MockFileAttributeProvider fileChecker;
-
- @Override
- protected void initTest(
- @NotNull Container applicationServices, @NotNull Container projectServices) {
- super.initTest(applicationServices, projectServices);
-
- fileChecker = new MockFileAttributeProvider();
- applicationServices.register(FileAttributeProvider.class, fileChecker);
- }
-
- @Test
- public void testManualPackagePaths() throws Exception {
- List<File> packagePaths =
- ImmutableList.of(
- new File("/path/to"),
- new File("/path/to/READONLY/root"),
- new File("/path/to/CUSTOM/root"));
-
- BlazeRoots blazeRoots =
- new BlazeRoots(
- new File(EXECUTION_ROOT),
- packagePaths,
- new ExecutionRootPath("root/blaze-out/crosstool/bin"),
- new ExecutionRootPath("root/blaze-out/crosstool/genfiles"),
- new File(OUTPUT_BASE));
-
- fileChecker.addFiles(
- new File("/path/to/com/google/Bla.java"),
- new File("/path/to/READONLY/root/com/google/Foo.java"),
- new File("/path/to/CUSTOM/root/com/other/Test.java"));
-
- ArtifactLocationDecoder decoder =
- new ArtifactLocationDecoderImpl(
- blazeRoots,
- new WorkspacePathResolverImpl(
- new WorkspaceRoot(new File("/path/to/root")), blazeRoots));
-
- ArtifactLocation blah =
- ArtifactLocation.builder().setRelativePath("com/google/Bla.java").setIsSource(true).build();
- assertThat(decoder.decode(blah).getPath()).isEqualTo("/path/to/com/google/Bla.java");
-
- ArtifactLocation foo =
- ArtifactLocation.builder().setRelativePath("com/google/Foo.java").setIsSource(true).build();
- assertThat(decoder.decode(foo).getPath())
- .isEqualTo("/path/to/READONLY/root/com/google/Foo.java");
-
- ArtifactLocation test =
- ArtifactLocation.builder().setRelativePath("com/other/Test.java").setIsSource(true).build();
- assertThat(decoder.decode(test).getPath())
- .isEqualTo("/path/to/CUSTOM/root/com/other/Test.java");
-
- ArtifactLocation.Builder temp =
- ArtifactLocation.builder().setRelativePath("third_party/other/Temp.java").setIsSource(true);
- assertThat(decoder.decode(temp.build()).getPath())
- .isEqualTo("/path/to/third_party/other/Temp.java");
- }
-
@Test
public void testGeneratedArtifact() throws Exception {
ArtifactLocation artifactLocation =
@@ -124,7 +45,6 @@
new ArtifactLocationDecoderImpl(
new BlazeRoots(
new File(EXECUTION_ROOT),
- ImmutableList.of(new File("/path/to/root")),
new ExecutionRootPath("root/blaze-out/crosstool/bin"),
new ExecutionRootPath("root/blaze-out/crosstool/genfiles"),
new File(OUTPUT_BASE)),
@@ -147,7 +67,6 @@
new ArtifactLocationDecoderImpl(
new BlazeRoots(
new File(EXECUTION_ROOT),
- ImmutableList.of(new File("/path/to/root")),
new ExecutionRootPath("root/blaze-out/crosstool/bin"),
new ExecutionRootPath("root/blaze-out/crosstool/genfiles"),
new File(OUTPUT_BASE)),
diff --git a/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ExecutionRootPathResolverTest.java b/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ExecutionRootPathResolverTest.java
index f880353..afba81b 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ExecutionRootPathResolverTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ExecutionRootPathResolverTest.java
@@ -19,9 +19,13 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.BlazeTestCase;
+import com.google.idea.blaze.base.bazel.BazelBuildSystemProvider;
+import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
+import com.intellij.openapi.extensions.ExtensionPoint;
import java.io.File;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -32,19 +36,23 @@
public class ExecutionRootPathResolverTest extends BlazeTestCase {
private static final WorkspaceRoot WORKSPACE_ROOT = new WorkspaceRoot(new File("/path/to/root"));
- private static final String EXECUTION_ROOT = "/path/to/_blaze_user/1234bf129e/root";
+ private static final String EXECUTION_ROOT = "/path/to/_bazel_user/1234bf129e/root";
- private static final BlazeRoots BLAZE_ROOTS =
- new BlazeRoots(
- new File(EXECUTION_ROOT),
- ImmutableList.of(WORKSPACE_ROOT.directory()),
- new ExecutionRootPath("blaze-out/crosstool/bin"),
- new ExecutionRootPath("blaze-out/crosstool/genfiles"),
- null);
+ private ExecutionRootPathResolver pathResolver;
- private final ExecutionRootPathResolver pathResolver =
- new ExecutionRootPathResolver(
- BLAZE_ROOTS, new WorkspacePathResolverImpl(WORKSPACE_ROOT, BLAZE_ROOTS));
+ @Override
+ protected void initTest(Container applicationServices, Container projectServices) {
+ ExtensionPoint<BuildSystemProvider> extensionPoint =
+ registerExtensionPoint(BuildSystemProvider.EP_NAME, BuildSystemProvider.class);
+ extensionPoint.registerExtension(new BazelBuildSystemProvider());
+
+ pathResolver =
+ new ExecutionRootPathResolver(
+ BuildSystem.Bazel,
+ WORKSPACE_ROOT,
+ new File(EXECUTION_ROOT),
+ new WorkspacePathResolverImpl(WORKSPACE_ROOT));
+ }
@Test
public void testExternalWorkspacePathRelativeToExecRoot() {
@@ -57,9 +65,9 @@
public void testGenfilesPathRelativeToExecRoot() {
ImmutableList<File> files =
pathResolver.resolveToIncludeDirectories(
- new ExecutionRootPath("blaze-out/crosstool/genfiles/res/normal"));
+ new ExecutionRootPath("bazel-out/crosstool/genfiles/res/normal"));
assertThat(files)
- .containsExactly(new File(EXECUTION_ROOT, "blaze-out/crosstool/genfiles/res/normal"));
+ .containsExactly(new File(EXECUTION_ROOT, "bazel-out/crosstool/genfiles/res/normal"));
}
@Test
@@ -68,4 +76,14 @@
pathResolver.resolveToIncludeDirectories(new ExecutionRootPath("tools/fast"));
assertThat(files).containsExactly(WORKSPACE_ROOT.fileForPath(new WorkspacePath("tools/fast")));
}
+
+ @Test
+ public void testGenfilesPathWithDifferentConfigSettingStillResolves() {
+ ImmutableList<File> files =
+ pathResolver.resolveToIncludeDirectories(
+ new ExecutionRootPath("bazel-out/arm-linux-fastbuild/genfiles/res/normal"));
+ assertThat(files)
+ .containsExactly(
+ new File(EXECUTION_ROOT, "bazel-out/arm-linux-fastbuild/genfiles/res/normal"));
+ }
}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImplTest.java b/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImplTest.java
index 282ea53..446d6ba 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImplTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImplTest.java
@@ -19,7 +19,6 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.BlazeTestCase;
-import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import java.io.File;
@@ -31,20 +30,10 @@
@RunWith(JUnit4.class)
public class WorkspacePathResolverImplTest extends BlazeTestCase {
private static final WorkspaceRoot WORKSPACE_ROOT = new WorkspaceRoot(new File("/path/to/root"));
- private static final String EXECUTION_ROOT = "/path/to/_blaze_user/1234bf129e/root";
-
- private static final BlazeRoots BLAZE_CITC_ROOTS =
- new BlazeRoots(
- new File(EXECUTION_ROOT),
- ImmutableList.of(WORKSPACE_ROOT.directory()),
- new ExecutionRootPath("blaze-out/crosstool/bin"),
- new ExecutionRootPath("blaze-out/crosstool/genfiles"),
- null);
@Test
public void testResolveToIncludeDirectories() {
- WorkspacePathResolver workspacePathResolver =
- new WorkspacePathResolverImpl(WORKSPACE_ROOT, BLAZE_CITC_ROOTS);
+ WorkspacePathResolver workspacePathResolver = new WorkspacePathResolverImpl(WORKSPACE_ROOT);
ImmutableList<File> files =
workspacePathResolver.resolveToIncludeDirectories(new WorkspacePath("tools/fast"));
assertThat(files).containsExactly(new File("/path/to/root/tools/fast"));
@@ -52,11 +41,18 @@
@Test
public void testResolveToIncludeDirectoriesForExecRootPath() {
- WorkspacePathResolver workspacePathResolver =
- new WorkspacePathResolverImpl(WORKSPACE_ROOT, BLAZE_CITC_ROOTS);
+ WorkspacePathResolver workspacePathResolver = new WorkspacePathResolverImpl(WORKSPACE_ROOT);
ImmutableList<File> files =
workspacePathResolver.resolveToIncludeDirectories(
new WorkspacePath("blaze-out/crosstool/bin/tools/fast"));
assertThat(files).containsExactly(new File("/path/to/root/blaze-out/crosstool/bin/tools/fast"));
}
+
+ @Test
+ public void testResolveToFile() {
+ WorkspacePathResolver workspacePathResolver = new WorkspacePathResolverImpl(WORKSPACE_ROOT);
+ WorkspacePath relativePath = new WorkspacePath("third_party/tools");
+ assertThat(workspacePathResolver.resolveToFile(relativePath))
+ .isEqualTo(WORKSPACE_ROOT.fileForPath(relativePath));
+ }
}
diff --git a/base/tests/utils/integration/com/google/idea/blaze/base/run/producer/BlazeRunConfigurationProducerTestCase.java b/base/tests/utils/integration/com/google/idea/blaze/base/run/producer/BlazeRunConfigurationProducerTestCase.java
new file mode 100644
index 0000000..0b34e07
--- /dev/null
+++ b/base/tests/utils/integration/com/google/idea/blaze/base/run/producer/BlazeRunConfigurationProducerTestCase.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2017 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.run.producer;
+
+import com.google.idea.blaze.base.BlazeIntegrationTestCase;
+import com.google.idea.blaze.base.EditorTestHelper;
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataManager;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.base.sync.SyncCache;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.intellij.execution.Location;
+import com.intellij.execution.PsiLocation;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.ide.DataManager;
+import com.intellij.idea.CommandLineApplication.MyDataManagerImpl;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.testFramework.MapDataContext;
+import javax.annotation.Nullable;
+import org.junit.After;
+import org.junit.Before;
+
+/** Run configuration producer integration test base */
+public class BlazeRunConfigurationProducerTestCase extends BlazeIntegrationTestCase {
+
+ protected EditorTestHelper editorTest;
+
+ @Before
+ public final void doSetup() {
+ BlazeProjectDataManager mockProjectDataManager =
+ new MockBlazeProjectDataManager(MockBlazeProjectDataBuilder.builder(workspaceRoot).build());
+ registerProjectService(BlazeProjectDataManager.class, mockProjectDataManager);
+ editorTest = new EditorTestHelper(getProject(), testFixture);
+
+ // IntelliJ replaces the normal DataManager with a mock version in headless environments.
+ // We rely on a functional DataManager in run configuration tests to recognize when multiple
+ // psi elements are selected.
+ DataManager dataManager =
+ new MyDataManagerImpl() {
+ DataContext dataContext;
+
+ @Override
+ public <T> void saveInDataContext(
+ DataContext dataContext, Key<T> dataKey, @Nullable T data) {
+ this.dataContext = dataContext;
+ super.saveInDataContext(dataContext, dataKey, data);
+ }
+
+ @Override
+ public DataContext getDataContext() {
+ return dataContext != null ? dataContext : super.getDataContext();
+ }
+ };
+ registerApplicationComponent(DataManager.class, dataManager);
+ }
+
+ @After
+ public final void doTearDown() {
+ SyncCache.getInstance(getProject()).clear();
+ }
+
+ protected PsiFile createAndIndexFile(WorkspacePath path, String... contents) {
+ PsiFile file = workspace.createPsiFile(path, contents);
+ editorTest.openFileInEditor(file); // open file to trigger update of indices
+ return file;
+ }
+
+ @Nullable
+ protected static String getTestFilterContents(BlazeCommandRunConfiguration config) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ config.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ return handlerState != null ? handlerState.getTestFilterFlag() : null;
+ }
+
+ @Nullable
+ protected static BlazeCommandName getCommandType(BlazeCommandRunConfiguration config) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ config.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ return handlerState != null ? handlerState.getCommand() : null;
+ }
+
+ protected ConfigurationContext createContextFromPsi(PsiElement element) {
+ final MapDataContext dataContext = new MapDataContext();
+ dataContext.put(CommonDataKeys.PROJECT, getProject());
+ dataContext.put(LangDataKeys.MODULE, ModuleUtil.findModuleForPsiElement(element));
+ dataContext.put(Location.DATA_KEY, PsiLocation.fromPsiElement(element));
+ return ConfigurationContext.getFromContext(dataContext);
+ }
+
+ protected ConfigurationContext createContextFromMultipleElements(PsiElement[] elements) {
+ final MapDataContext dataContext = new MapDataContext();
+ dataContext.put(CommonDataKeys.PROJECT, getProject());
+ dataContext.put(LangDataKeys.MODULE, ModuleUtil.findModuleForPsiElement(elements[0]));
+ dataContext.put(Location.DATA_KEY, PsiLocation.fromPsiElement(elements[0]));
+ dataContext.put(LangDataKeys.PSI_ELEMENT_ARRAY, elements);
+ return ConfigurationContext.getFromContext(dataContext);
+ }
+
+ @Nullable
+ protected RunConfiguration createConfigurationFromLocation(PsiFile psiFile) {
+ MapDataContext dataContext = new MapDataContext();
+ dataContext.put(CommonDataKeys.PROJECT, getProject());
+ dataContext.put(LangDataKeys.MODULE, ModuleUtil.findModuleForPsiElement(psiFile));
+ dataContext.put(Location.DATA_KEY, PsiLocation.fromPsiElement(psiFile));
+ RunnerAndConfigurationSettings settings =
+ ConfigurationContext.getFromContext(dataContext).getConfiguration();
+ return settings != null ? settings.getConfiguration() : null;
+ }
+
+ protected static ArtifactLocation sourceRoot(String relativePath) {
+ return ArtifactLocation.builder().setRelativePath(relativePath).setIsSource(true).build();
+ }
+}
diff --git a/base/tests/utils/integration/com/google/idea/blaze/base/sync/BlazeSyncIntegrationTestCase.java b/base/tests/utils/integration/com/google/idea/blaze/base/sync/BlazeSyncIntegrationTestCase.java
index 53c6b53..e6b8453 100644
--- a/base/tests/utils/integration/com/google/idea/blaze/base/sync/BlazeSyncIntegrationTestCase.java
+++ b/base/tests/utils/integration/com/google/idea/blaze/base/sync/BlazeSyncIntegrationTestCase.java
@@ -55,6 +55,7 @@
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverImpl;
import com.google.idea.blaze.base.vcs.BlazeVcsHandler;
import com.intellij.ide.IdeEventQueue;
+import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
@@ -87,6 +88,26 @@
protected BlazeContext context;
private ImmutableList<ContentEntry> workspaceContentEntries = ImmutableList.of();
+ private Map<String, ModifiableRootModel> modules = Maps.newHashMap();
+
+ private class MockModuleEditor extends ModuleEditorImpl {
+ public MockModuleEditor(Project project, BlazeImportSettings importSettings) {
+ super(project, importSettings);
+ }
+
+ @Override
+ public void commit() {
+ // don't commit module changes,
+ // and make sure they're properly disposed when the test is finished
+ for (ModifiableRootModel model : modules.values()) {
+ Disposer.register(getTestRootDisposable(), model::dispose);
+ if (model.getModule().getName().equals(BlazeDataStorage.WORKSPACE_MODULE_NAME)) {
+ workspaceContentEntries = ImmutableList.copyOf(model.getContentEntries());
+ }
+ }
+ BlazeSyncIntegrationTestCase.this.modules = modules;
+ }
+ }
@Before
public void doSetup() throws Exception {
@@ -98,27 +119,7 @@
registerExtension(BlazeVcsHandler.EP_NAME, vcsHandler);
registerApplicationService(BlazeInfo.class, blazeInfoData);
registerApplicationService(BlazeIdeInterface.class, blazeIdeInterface);
- registerApplicationService(
- ModuleEditorProvider.class,
- new ModuleEditorProvider() {
- @Override
- public ModuleEditorImpl getModuleEditor(
- Project project, BlazeImportSettings importSettings) {
- return new ModuleEditorImpl(project, importSettings) {
- @Override
- public void commit() {
- // don't commit module changes,
- // and make sure they're properly disposed when the test is finished
- for (ModifiableRootModel model : modules.values()) {
- Disposer.register(getTestRootDisposable(), model::dispose);
- if (model.getModule().getName().equals(BlazeDataStorage.WORKSPACE_MODULE_NAME)) {
- workspaceContentEntries = ImmutableList.copyOf(model.getContentEntries());
- }
- }
- }
- };
- }
- });
+ registerApplicationService(ModuleEditorProvider.class, MockModuleEditor::new);
errorCollector = new ErrorCollector();
context = new BlazeContext();
@@ -145,6 +146,12 @@
return workspaceContentEntries;
}
+ /** The modules created during sync */
+ protected Module getModuleCreatedDuringSync(String module) {
+ ModifiableRootModel modifiableRootModel = modules.get(module);
+ return modifiableRootModel != null ? modifiableRootModel.getModule() : null;
+ }
+
/** Search the workspace module's {@link ContentEntry}s for one with the given file. */
@Nullable
protected ContentEntry findContentEntry(VirtualFile root) {
@@ -268,7 +275,7 @@
@Override
public ListenableFuture<String> runBlazeInfo(
@Nullable BlazeContext context,
- BuildSystem buildSystem,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags,
String key) {
@@ -278,7 +285,7 @@
@Override
public ListenableFuture<byte[]> runBlazeInfoGetBytes(
@Nullable BlazeContext context,
- BuildSystem buildSystem,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags,
String key) {
@@ -288,7 +295,7 @@
@Override
public ListenableFuture<ImmutableMap<String, String>> runBlazeInfo(
@Nullable BlazeContext context,
- BuildSystem buildSystem,
+ String binaryPath,
WorkspaceRoot workspaceRoot,
List<String> blazeFlags) {
return Futures.immediateFuture(ImmutableMap.copyOf(results));
diff --git a/base/tests/utils/unit/com/google/idea/blaze/base/TestUtils.java b/base/tests/utils/unit/com/google/idea/blaze/base/TestUtils.java
index f040cf2..e0f2d47 100644
--- a/base/tests/utils/unit/com/google/idea/blaze/base/TestUtils.java
+++ b/base/tests/utils/unit/com/google/idea/blaze/base/TestUtils.java
@@ -37,8 +37,8 @@
import java.io.Serializable;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.picocontainer.PicoContainer;
/** Test utilities. */
diff --git a/base/tests/utils/unit/com/google/idea/blaze/base/model/MockBlazeProjectDataBuilder.java b/base/tests/utils/unit/com/google/idea/blaze/base/model/MockBlazeProjectDataBuilder.java
index 25bd08d..28b4b9c 100644
--- a/base/tests/utils/unit/com/google/idea/blaze/base/model/MockBlazeProjectDataBuilder.java
+++ b/base/tests/utils/unit/com/google/idea/blaze/base/model/MockBlazeProjectDataBuilder.java
@@ -15,7 +15,6 @@
*/
package com.google.idea.blaze.base.model;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
@@ -30,11 +29,12 @@
import com.google.idea.blaze.base.sync.workspace.BlazeRoots;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverImpl;
+import java.io.File;
/**
- * Use to build mock praject data for tests.
+ * Use to build mock project data for tests.
*
- * <p>For any data you don't supply, the builder make a best-effort attempt to create default
+ * <p>For any data you don't supply, the builder makes a best-effort attempt to create default
* objects using whatever data you have supplied if applicable.
*/
public class MockBlazeProjectDataBuilder {
@@ -51,7 +51,7 @@
private SyncState syncState;
private ImmutableMultimap<TargetKey, TargetKey> reverseDependencies;
- public MockBlazeProjectDataBuilder(WorkspaceRoot workspaceRoot) {
+ private MockBlazeProjectDataBuilder(WorkspaceRoot workspaceRoot) {
this.workspaceRoot = workspaceRoot;
}
@@ -122,8 +122,7 @@
this.blazeRoots != null
? this.blazeRoots
: new BlazeRoots(
- null,
- ImmutableList.of(workspaceRoot.directory()),
+ new File(workspaceRoot.directory().getParentFile(), "exec_root"),
new ExecutionRootPath("bin"),
new ExecutionRootPath("gen"),
null);
@@ -132,7 +131,7 @@
WorkspacePathResolver workspacePathResolver =
this.workspacePathResolver != null
? this.workspacePathResolver
- : new WorkspacePathResolverImpl(workspaceRoot, blazeRoots);
+ : new WorkspacePathResolverImpl(workspaceRoot);
ArtifactLocationDecoder artifactLocationDecoder =
this.artifactLocationDecoder != null
? this.artifactLocationDecoder
diff --git a/clwb/BUILD b/clwb/BUILD
index f1048b9..fbd119b 100644
--- a/clwb/BUILD
+++ b/clwb/BUILD
@@ -49,6 +49,7 @@
"//common/experiments",
"//cpp",
"//intellij_platform_sdk:plugin_api",
+ "//sdkcompat",
"@jsr305_annotations//jar",
],
)
diff --git a/clwb/src/META-INF/clwb.xml b/clwb/src/META-INF/clwb.xml
index 222ef38..32e7b0a 100644
--- a/clwb/src/META-INF/clwb.xml
+++ b/clwb/src/META-INF/clwb.xml
@@ -50,6 +50,7 @@
<SyncPlugin implementation="com.google.idea.blaze.clwb.sync.BlazeCLionSyncPlugin"/>
<BlazeCommandRunConfigurationHandlerProvider implementation="com.google.idea.blaze.clwb.run.BlazeCidrRunConfigurationHandlerProvider" order="first"/>
<RunConfigurationFactory implementation="com.google.idea.blaze.clwb.run.BlazeCidrDebuggableConfigurationFactory"/>
+ <BlazeTestEventsHandler implementation="com.google.idea.blaze.clwb.run.test.BlazeCidrTestEventsHandler"/>
</extensions>
<actions>
diff --git a/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsole.java b/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsole.java
index 543f346..725dde4 100644
--- a/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsole.java
+++ b/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsole.java
@@ -36,7 +36,7 @@
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.concurrency.SequentialTaskExecutor;
+import com.intellij.util.concurrency.BoundedTaskExecutor;
import com.intellij.util.ui.MessageCategory;
import com.intellij.util.ui.UIUtil;
import java.util.ArrayList;
@@ -44,6 +44,7 @@
import java.util.List;
import java.util.StringTokenizer;
import java.util.UUID;
+import java.util.concurrent.ExecutorService;
import javax.swing.Icon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -58,8 +59,8 @@
EnumSet.allOf(ErrorTreeElementKind.class);
private final ProblemsViewPanel myPanel;
- private final SequentialTaskExecutor myViewUpdater =
- new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
+ private final ExecutorService myViewUpdater =
+ new BoundedTaskExecutor(PooledThreadExecutor.INSTANCE, 1);
private final Icon myActiveIcon = AllIcons.Toolwindows.Problems;
private final Icon myPassiveIcon = IconLoader.getDisabledIcon(myActiveIcon);
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrDebuggableConfigurationFactory.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrDebuggableConfigurationFactory.java
index 5363e69..5e740f3 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrDebuggableConfigurationFactory.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrDebuggableConfigurationFactory.java
@@ -15,9 +15,7 @@
*/
package com.google.idea.blaze.clwb.run;
-import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.command.BlazeCommandName;
-import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.ideinfo.TargetKey;
import com.google.idea.blaze.base.model.BlazeProjectData;
@@ -58,7 +56,6 @@
if (state != null) {
if (kind != null && Kind.isTestRule(kind.toString())) {
state.setCommand(BlazeCommandName.TEST);
- state.setBlazeFlags(ImmutableList.of(BlazeFlags.TEST_OUTPUT_STREAMED));
} else {
state.setCommand(BlazeCommandName.RUN);
}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrLauncher.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrLauncher.java
index 410cf57..f5ca00e 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrLauncher.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrLauncher.java
@@ -26,14 +26,18 @@
import com.google.idea.blaze.base.projectview.ProjectViewManager;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.DistributedExecutorSupport;
import com.google.idea.blaze.base.run.processhandler.LineProcessingProcessAdapter;
import com.google.idea.blaze.base.run.processhandler.ScopedBlazeProcessHandler;
+import com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler;
+import com.google.idea.blaze.base.run.smrunner.SmRunnerUtils;
import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.scopes.IssuesScope;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
+import com.google.idea.sdkcompat.cidr.CidrConsoleBuilderAdapter;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.CommandLineState;
import com.intellij.execution.configurations.GeneralCommandLine;
@@ -50,10 +54,8 @@
import com.jetbrains.cidr.execution.debugger.CidrDebugProcess;
import com.jetbrains.cidr.execution.debugger.CidrLocalDebugProcess;
import com.jetbrains.cidr.execution.testing.CidrLauncher;
-import com.jetbrains.cidr.execution.testing.OCGoogleTestConsoleProperties;
import java.io.File;
-import java.util.Objects;
-import org.jetbrains.annotations.NotNull;
+import javax.annotation.Nullable;
/**
* Handles running/debugging cc_test and cc_binary targets in CLion. Sets up gdb when debugging, and
@@ -68,7 +70,7 @@
private final BlazeCidrRunConfigurationRunner runner;
private final ExecutionEnvironment executionEnvironment;
- public BlazeCidrLauncher(
+ BlazeCidrLauncher(
BlazeCommandRunConfiguration configuration,
BlazeCidrRunConfigurationRunner runner,
ExecutionEnvironment environment) {
@@ -89,26 +91,39 @@
ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
LOG.assertTrue(projectViewSet != null);
- state.setConsoleBuilder(createConsoleBuilder());
+ ImmutableList<String> testHandlerFlags = ImmutableList.of();
+ BlazeTestEventsHandler testEventsHandler =
+ useTestUi()
+ ? BlazeTestEventsHandler.getHandlerForTarget(project, configuration.getTarget())
+ : null;
+ if (testEventsHandler != null) {
+ testHandlerFlags = BlazeTestEventsHandler.getBlazeFlags(project);
+ }
- BlazeCommand blazeCommand =
- BlazeCommand.builder(Blaze.getBuildSystem(project), handlerState.getCommand())
+ BlazeCommand.Builder command =
+ BlazeCommand.builder(
+ Blaze.getBuildSystemProvider(project).getBinaryPath(), handlerState.getCommand())
.addTargets(configuration.getTarget())
.addBlazeFlags(BlazeFlags.buildFlags(project, ProjectViewSet.builder().build()))
+ .addBlazeFlags(testHandlerFlags)
.addBlazeFlags(handlerState.getBlazeFlags())
- .addExeFlags(handlerState.getExeFlags())
- .build();
+ .addExeFlags(handlerState.getExeFlags());
+
+ command.addBlazeFlags(
+ DistributedExecutorSupport.getBlazeFlags(
+ project, handlerState.getRunOnDistributedExecutor()));
+
+ state.setConsoleBuilder(createConsoleBuilder(testEventsHandler));
WorkspaceRoot workspaceRoot = WorkspaceRoot.fromImportSettings(importSettings);
return new ScopedBlazeProcessHandler(
project,
- blazeCommand,
+ command.build(),
workspaceRoot,
new ScopedBlazeProcessHandler.ScopedProcessHandlerDelegate() {
@Override
public void onBlazeContextStart(BlazeContext context) {
- context
- .push(new IssuesScope(project));
+ context.push(new IssuesScope(project));
}
@Override
@@ -145,24 +160,21 @@
CLionRunParameters parameters =
new CLionRunParameters(
new BlazeGDBDriverConfiguration(project, startupCommands, workspaceRoot), installer);
- CidrDebugProcess result =
- new CidrLocalDebugProcess(parameters, session, state.getConsoleBuilder());
- return result;
+ return new CidrLocalDebugProcess(parameters, session, state.getConsoleBuilder());
}
- @NotNull
@Override
protected Project getProject() {
return project;
}
- private CidrConsoleBuilder createConsoleBuilder() {
- if (Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)) {
- // Use the Google Test failure/success console instead of a standard console.
- return new GoogleTestConsoleBuilder(configuration.getProject());
+ private CidrConsoleBuilder createConsoleBuilder(
+ @Nullable BlazeTestEventsHandler testEventsHandler) {
+ if (testEventsHandler != null) {
+ return new GoogleTestConsoleBuilder(configuration.getProject(), testEventsHandler);
}
- return new CidrConsoleBuilder(configuration.getProject());
+ return new CidrConsoleBuilderAdapter(configuration.getProject());
}
private ImmutableList<String> getGdbStartupCommands(File workingDir) {
@@ -176,20 +188,27 @@
return ImmutableList.of(subPathCommand);
}
- private final class GoogleTestConsoleBuilder extends CidrConsoleBuilder {
- private GoogleTestConsoleBuilder(Project project) {
+ private boolean useTestUi() {
+ return BlazeCommandName.TEST.equals(handlerState.getCommand())
+ && !handlerState.getRunOnDistributedExecutor();
+ }
+
+ private final class GoogleTestConsoleBuilder extends CidrConsoleBuilderAdapter {
+ private final BlazeTestEventsHandler testEventsHandler;
+
+ private GoogleTestConsoleBuilder(Project project, BlazeTestEventsHandler testEventsHandler) {
super(project);
+ this.testEventsHandler = testEventsHandler;
addFilter(new BlazeCidrTestOutputFilter(project));
}
@Override
protected ConsoleView createConsole() {
- OCGoogleTestConsoleProperties consoleProperties =
- new OCGoogleTestConsoleProperties(
- configuration,
- executionEnvironment.getExecutor(),
- executionEnvironment.getExecutionTarget());
- return createConsole(configuration.getType(), consoleProperties);
+ return SmRunnerUtils.getConsoleView(
+ configuration.getProject(),
+ configuration,
+ executionEnvironment.getExecutor(),
+ testEventsHandler);
}
}
}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java
index 208cf11..c1b1f8d 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java
@@ -123,7 +123,9 @@
context.output(new StatusOutput("Building debug binary"));
BlazeCommand.Builder command =
- BlazeCommand.builder(Blaze.getBuildSystem(project), BlazeCommandName.BUILD)
+ BlazeCommand.builder(
+ Blaze.getBuildSystemProvider(project).getBinaryPath(),
+ BlazeCommandName.BUILD)
.addTargets(configuration.getTarget())
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
.addBlazeFlags(handlerState.getBlazeFlags());
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrTestOutputFilter.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrTestOutputFilter.java
index b2498f1..cdd8900 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrTestOutputFilter.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrTestOutputFilter.java
@@ -22,7 +22,7 @@
import com.intellij.execution.filters.RegexpFilter;
import com.intellij.openapi.project.Project;
import java.io.File;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Identifies file paths in CLion test output which aren't found by CidrPathConsoleFilter. */
public class BlazeCidrTestOutputFilter extends RegexpFilter {
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCommandFlags.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCommandFlags.java
deleted file mode 100644
index 12020f2..0000000
--- a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCommandFlags.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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.clwb.run;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.base.ui.UiUtil;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.JDOMExternalizable;
-import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.util.execution.ParametersListUtil;
-import java.util.List;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JTextArea;
-import org.jdom.Element;
-
-final class BlazeCommandFlags implements JDOMExternalizable {
- public static final class Editor {
- private final JTextArea blazeFlagsField = new JTextArea(5, 0);
- private final JTextArea exeFlagsField = new JTextArea(5, 0);
-
- public JComponent getEditorComponent() {
- return UiUtil.createBox(
- new JLabel("Blaze flags:"),
- blazeFlagsField,
- new JLabel("Executable flags:"),
- exeFlagsField);
- }
-
- public void setText(BlazeCommandFlags blazeCommandFlags) {
- blazeFlagsField.setText(ParametersListUtil.join(blazeCommandFlags.getBlazeFlags()));
- exeFlagsField.setText(ParametersListUtil.join(blazeCommandFlags.getExeFlags()));
- }
-
- public BlazeCommandFlags getBlazeCommandFlags() {
- ImmutableList<String> blazeFlags =
- ImmutableList.copyOf(
- ParametersListUtil.parse(Strings.nullToEmpty(blazeFlagsField.getText())));
- ImmutableList<String> exeFlags =
- ImmutableList.copyOf(
- ParametersListUtil.parse(Strings.nullToEmpty(exeFlagsField.getText())));
- return new BlazeCommandFlags(blazeFlags, exeFlags);
- }
- }
-
- private static final String USER_BLAZE_FLAG_TAG = "blaze-user-flag";
- private static final String USER_EXE_FLAG_TAG = "blaze-user-exe-flag";
-
- private ImmutableList<String> blazeFlags = ImmutableList.of();
- private ImmutableList<String> exeFlags = ImmutableList.of();
-
- public BlazeCommandFlags() {
- this.blazeFlags = ImmutableList.of();
- this.exeFlags = ImmutableList.of();
- }
-
- public BlazeCommandFlags(ImmutableList<String> blazeFlags, ImmutableList<String> exeFlags) {
- this.blazeFlags = blazeFlags;
- this.exeFlags = exeFlags;
- }
-
- public ImmutableList<String> getBlazeFlags() {
- return blazeFlags;
- }
-
- public ImmutableList<String> getExeFlags() {
- return exeFlags;
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- blazeFlags = loadUserFlags(element, USER_BLAZE_FLAG_TAG);
- exeFlags = loadUserFlags(element, USER_EXE_FLAG_TAG);
- }
-
- private static ImmutableList<String> loadUserFlags(Element root, String tag) {
- ImmutableList.Builder<String> flagsBuilder = ImmutableList.builder();
- for (Element e : root.getChildren(tag)) {
- String flag = e.getTextTrim();
- if (flag != null && !flag.isEmpty()) {
- flagsBuilder.add(flag);
- }
- }
- return flagsBuilder.build();
- }
-
- @Override
- public void writeExternal(Element element) throws WriteExternalException {
- saveUserFlags(element, blazeFlags, USER_BLAZE_FLAG_TAG);
- saveUserFlags(element, exeFlags, USER_EXE_FLAG_TAG);
- }
-
- private static void saveUserFlags(Element root, List<String> flags, String tag) {
- for (String flag : flags) {
- Element child = new Element(tag);
- child.setText(flag);
- root.addContent(child);
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- BlazeCommandFlags that = (BlazeCommandFlags) o;
- return Objects.equal(blazeFlags, that.blazeFlags) && Objects.equal(exeFlags, that.exeFlags);
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(blazeFlags, exeFlags);
- }
-}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java b/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java
index 3589c9a..0a48b17 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java
@@ -17,33 +17,17 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.command.BlazeCommandName;
-import com.google.idea.blaze.base.command.BlazeFlags;
-import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.TestTargetHeuristic;
import com.google.idea.blaze.base.run.producers.BlazeRunConfigurationProducer;
import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.clwb.run.test.BlazeCidrTestTarget;
import com.intellij.execution.Location;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.jetbrains.cidr.execution.testing.CidrTestUtil;
-import com.jetbrains.cidr.lang.psi.OCFile;
-import com.jetbrains.cidr.lang.psi.OCFunctionDefinition;
-import com.jetbrains.cidr.lang.psi.OCMacroCall;
-import com.jetbrains.cidr.lang.psi.OCMacroCallArgument;
-import com.jetbrains.cidr.lang.psi.OCStruct;
-import com.jetbrains.cidr.lang.symbols.OCSymbol;
-import com.jetbrains.cidr.lang.symbols.cpp.OCFunctionSymbol;
-import com.jetbrains.cidr.lang.symbols.cpp.OCStructSymbol;
-import com.jetbrains.cidr.lang.symbols.cpp.OCSymbolWithQualifiedName;
-import java.util.Collection;
-import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
@@ -51,52 +35,6 @@
public class BlazeCidrTestConfigurationProducer
extends BlazeRunConfigurationProducer<BlazeCommandRunConfiguration> {
- private static class TestTarget {
- @Nullable
- private static TestTarget createFromFile(@Nullable PsiElement element) {
- return createFromClassAndMethod(element, null, null);
- }
-
- @Nullable
- private static TestTarget createFromClass(@Nullable PsiElement element, String className) {
- return createFromClassAndMethod(element, className, null);
- }
-
- @Nullable
- private static TestTarget createFromClassAndMethod(
- @Nullable PsiElement element, String classOrSuiteName, @Nullable String testName) {
- Label label = TestTargetHeuristic.testTargetForPsiElement(element);
- if (label == null) {
- return null;
- }
- String filter = null;
- if (classOrSuiteName != null) {
- filter = classOrSuiteName;
- if (testName != null) {
- filter += "." + testName;
- }
- }
- return new TestTarget(element, label, filter);
- }
-
- private final PsiElement element;
- private final Label label;
- @Nullable private final String testFilterArg;
- private final String name;
-
- private TestTarget(PsiElement element, Label label, @Nullable String testFilter) {
- this.element = element;
- this.label = label;
- if (testFilter != null) {
- testFilterArg = BlazeFlags.TEST_FILTER + "=" + testFilter;
- name = String.format("%s (%s)", testFilter, label.toString());
- } else {
- testFilterArg = null;
- name = label.toString();
- }
- }
- }
-
public BlazeCidrTestConfigurationProducer() {
super(BlazeCommandRunConfigurationType.getInstance());
}
@@ -122,7 +60,7 @@
if (element == null) {
return false;
}
- TestTarget testObject = findTestObject(element);
+ BlazeCidrTestTarget testObject = BlazeCidrTestTarget.findTestObject(element);
if (testObject == null) {
return false;
}
@@ -136,10 +74,10 @@
handlerState.setCommand(BlazeCommandName.TEST);
ImmutableList.Builder<String> flags = ImmutableList.builder();
- if (testObject.testFilterArg != null) {
- flags.add(testObject.testFilterArg);
+ String testFilter = testObject.getTestFilterFlag();
+ if (testFilter != null) {
+ flags.add(testFilter);
}
- flags.add(BlazeFlags.TEST_OUTPUT_STREAMED);
flags.addAll(handlerState.getBlazeFlags());
handlerState.setBlazeFlags(flags.build());
@@ -164,100 +102,11 @@
if (element == null) {
return false;
}
- TestTarget testObject = findTestObject(element);
+ BlazeCidrTestTarget testObject = BlazeCidrTestTarget.findTestObject(element);
if (testObject == null) {
return false;
}
- List<String> flags = handlerState.getBlazeFlags();
return testObject.label.equals(configuration.getTarget())
- && (testObject.testFilterArg == null || flags.contains(testObject.testFilterArg));
- }
-
- @Nullable
- private static TestTarget findTestObject(PsiElement element) {
- // Copied from on CidrGoogleTestRunConfigurationProducer::findTestObject.
- // Precedence order (decreasing): class/function, macro, file
- PsiElement parent =
- PsiTreeUtil.getNonStrictParentOfType(element, OCFunctionDefinition.class, OCStruct.class);
-
- OCStructSymbol parentSymbol;
- if (parent instanceof OCStruct
- && ((parentSymbol = ((OCStruct) parent).getSymbol()) != null)
- && CidrTestUtil.isGoogleTestClass(parentSymbol)) {
- Couple<String> name = CidrTestUtil.extractGoogleTestName(parentSymbol);
- if (name != null) {
- return TestTarget.createFromClassAndMethod(parent, name.first, name.second);
- }
- String className = parentSymbol.getQualifiedName().getName();
- return TestTarget.createFromClass(parent, className);
- } else if (parent instanceof OCFunctionDefinition) {
- OCFunctionSymbol symbol = ((OCFunctionDefinition) parent).getSymbol();
- if (symbol != null) {
- OCSymbolWithQualifiedName<?> resolvedOwner = symbol.getResolvedOwner();
- if (resolvedOwner != null) {
- OCSymbol<?> owner = resolvedOwner.getDefinitionSymbol();
- if (owner instanceof OCStructSymbol
- && CidrTestUtil.isGoogleTestClass((OCStructSymbol) owner)) {
- OCStruct struct = (OCStruct) owner.locateDefinition();
- Couple<String> name = CidrTestUtil.extractGoogleTestName((OCStructSymbol) owner);
- if (name != null) {
- return TestTarget.createFromClassAndMethod(struct, name.first, name.second);
- }
- return TestTarget.createFromClass(
- struct, ((OCStructSymbol) owner).getQualifiedName().getName());
- }
- }
- }
- }
-
- // if we're still here, let's test for a macro and, as a last resort, a file.
- parent = PsiTreeUtil.getNonStrictParentOfType(element, OCMacroCall.class, OCFile.class);
- if (parent instanceof OCMacroCall) {
- OCMacroCall gtestMacro = CidrTestUtil.findGoogleTestMacros(parent);
- if (gtestMacro != null) {
- List<OCMacroCallArgument> arguments = gtestMacro.getArguments();
- if (arguments.size() >= 2) {
- OCMacroCallArgument suiteArg = arguments.get(0);
- OCMacroCallArgument testArg = arguments.get(1);
-
- // if the element is the first argument of macro call,
- // then running entire suite, otherwise only a current test
- boolean isSuite =
- isFirstArgument(PsiTreeUtil.getParentOfType(element, OCMacroCallArgument.class))
- || isFirstArgument(element.getPrevSibling());
- String suiteName = CidrTestUtil.extractArgumentValue(suiteArg);
- String testName = CidrTestUtil.extractArgumentValue(testArg);
- OCStructSymbol symbol =
- CidrTestUtil.findGoogleTestSymbol(element.getProject(), suiteName, testName);
- if (symbol != null) {
- OCStruct targetElement = (OCStruct) symbol.locateDefinition();
- return TestTarget.createFromClassAndMethod(
- targetElement, suiteName, isSuite ? null : testName);
- }
- }
- }
- Couple<String> suite = CidrTestUtil.extractFullSuiteNameFromMacro(parent);
- if (suite != null) {
- Collection<OCStructSymbol> res =
- CidrTestUtil.findGoogleTestSymbolsForSuiteRandomly(
- element.getProject(), suite.first, true);
- if (res.size() != 0) {
- OCStruct struct = (OCStruct) res.iterator().next().locateDefinition();
- return TestTarget.createFromClassAndMethod(struct, suite.first, null);
- }
- }
- } else if (parent instanceof OCFile) {
- return TestTarget.createFromFile(parent);
- }
- return null;
- }
-
- private static boolean isFirstArgument(@Nullable PsiElement element) {
- OCMacroCall macroCall = PsiTreeUtil.getParentOfType(element, OCMacroCall.class);
- if (macroCall != null) {
- List<OCMacroCallArgument> arguments = macroCall.getArguments();
- return arguments.size() > 0 && arguments.get(0).equals(element);
- }
- return false;
+ && Objects.equals(handlerState.getTestFilterFlag(), testObject.getTestFilterFlag());
}
}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestEventsHandler.java b/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestEventsHandler.java
new file mode 100644
index 0000000..831a81b
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestEventsHandler.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2017 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.clwb.run.test;
+
+import com.google.common.base.Joiner;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.model.primitives.Kind;
+import com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler;
+import com.intellij.execution.Location;
+import com.intellij.execution.testframework.sm.runner.SMTestLocator;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.io.URLUtil;
+import com.jetbrains.cidr.execution.testing.OCGoogleTestLocationProvider;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/** Provides C/C++ specific methods needed by the SM-runner test UI. */
+public class BlazeCidrTestEventsHandler extends BlazeTestEventsHandler {
+
+ @Override
+ protected EnumSet<Kind> handledKinds() {
+ return EnumSet.of(Kind.CC_TEST);
+ }
+
+ @Override
+ public SMTestLocator getTestLocator() {
+ return OCGoogleTestLocationProvider.INSTANCE;
+ }
+
+ @Nullable
+ @Override
+ public String getTestFilter(Project project, List<Location<?>> testLocations) {
+ List<String> filters = new ArrayList<>();
+ for (Location<?> location : testLocations) {
+ BlazeCidrTestTarget target = BlazeCidrTestTarget.findTestObject(location.getPsiElement());
+ if (target != null && target.testFilter != null) {
+ filters.add(target.testFilter);
+ }
+ }
+ if (filters.isEmpty()) {
+ return null;
+ }
+ return String.format("%s=%s", BlazeFlags.TEST_FILTER, Joiner.on(':').join(filters));
+ }
+
+ @Override
+ public String suiteLocationUrl(@Nullable Kind kind, String name) {
+ return OCGoogleTestLocationProvider.PROTOCOL + URLUtil.SCHEME_SEPARATOR + name;
+ }
+
+ @Override
+ public String testLocationUrl(
+ @Nullable Kind kind, String parentSuite, String name, @Nullable String className) {
+ if (className == null) {
+ return OCGoogleTestLocationProvider.PROTOCOL + URLUtil.SCHEME_SEPARATOR + name;
+ }
+ return OCGoogleTestLocationProvider.PROTOCOL
+ + URLUtil.SCHEME_SEPARATOR
+ + className
+ + "."
+ + name;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestTarget.java b/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestTarget.java
new file mode 100644
index 0000000..acf3966
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestTarget.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2017 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.clwb.run.test;
+
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.run.TestTargetHeuristic;
+import com.intellij.openapi.util.Couple;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.cidr.execution.testing.CidrTestUtil;
+import com.jetbrains.cidr.lang.psi.OCFile;
+import com.jetbrains.cidr.lang.psi.OCFunctionDefinition;
+import com.jetbrains.cidr.lang.psi.OCMacroCall;
+import com.jetbrains.cidr.lang.psi.OCMacroCallArgument;
+import com.jetbrains.cidr.lang.psi.OCStruct;
+import com.jetbrains.cidr.lang.symbols.OCSymbol;
+import com.jetbrains.cidr.lang.symbols.cpp.OCFunctionSymbol;
+import com.jetbrains.cidr.lang.symbols.cpp.OCStructSymbol;
+import com.jetbrains.cidr.lang.symbols.cpp.OCSymbolWithQualifiedName;
+import java.util.Collection;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/** A blaze cpp test target, together with optional test filter. */
+public class BlazeCidrTestTarget {
+
+ public final PsiElement element;
+ public final Label label;
+ @Nullable public final String testFilter;
+ public final String name;
+
+ private BlazeCidrTestTarget(PsiElement element, Label label, @Nullable String testFilter) {
+ this.element = element;
+ this.label = label;
+ this.testFilter = testFilter;
+ if (testFilter != null) {
+ name = String.format("%s (%s)", testFilter, label.toString());
+ } else {
+ name = label.toString();
+ }
+ }
+
+ /** The raw test filter string with '--test_filter=' prepended, or null if there is no filter. */
+ @Nullable
+ public String getTestFilterFlag() {
+ return testFilter != null ? BlazeFlags.TEST_FILTER + "=" + testFilter : null;
+ }
+
+ @Nullable
+ private static BlazeCidrTestTarget createFromFile(@Nullable PsiElement element) {
+ return createFromClassAndMethod(element, null, null);
+ }
+
+ @Nullable
+ private static BlazeCidrTestTarget createFromClass(
+ @Nullable PsiElement element, String className) {
+ return createFromClassAndMethod(element, className, null);
+ }
+
+ @Nullable
+ private static BlazeCidrTestTarget createFromClassAndMethod(
+ @Nullable PsiElement element, String classOrSuiteName, @Nullable String testName) {
+ Label label = TestTargetHeuristic.testTargetForPsiElement(element);
+ if (label == null) {
+ return null;
+ }
+ String filter = null;
+ if (classOrSuiteName != null) {
+ filter = classOrSuiteName;
+ if (testName != null) {
+ filter += "." + testName;
+ }
+ }
+ return new BlazeCidrTestTarget(element, label, filter);
+ }
+
+ @Nullable
+ public static BlazeCidrTestTarget findTestObject(PsiElement element) {
+ // Copied from on CidrGoogleTestRunConfigurationProducer::findTestObject.
+ // Precedence order (decreasing): class/function, macro, file
+ PsiElement parent =
+ PsiTreeUtil.getNonStrictParentOfType(element, OCFunctionDefinition.class, OCStruct.class);
+
+ OCStructSymbol parentSymbol;
+ if (parent instanceof OCStruct
+ && ((parentSymbol = ((OCStruct) parent).getSymbol()) != null)
+ && CidrTestUtil.isGoogleTestClass(parentSymbol)) {
+ Couple<String> name = CidrTestUtil.extractGoogleTestName(parentSymbol);
+ if (name != null) {
+ return createFromClassAndMethod(parent, name.first, name.second);
+ }
+ String className = parentSymbol.getQualifiedName().getName();
+ return createFromClass(parent, className);
+ } else if (parent instanceof OCFunctionDefinition) {
+ OCFunctionSymbol symbol = ((OCFunctionDefinition) parent).getSymbol();
+ if (symbol != null) {
+ OCSymbolWithQualifiedName<?> resolvedOwner = symbol.getResolvedOwner();
+ if (resolvedOwner != null) {
+ OCSymbol<?> owner = resolvedOwner.getDefinitionSymbol();
+ if (owner instanceof OCStructSymbol
+ && CidrTestUtil.isGoogleTestClass((OCStructSymbol) owner)) {
+ OCStruct struct = (OCStruct) owner.locateDefinition();
+ Couple<String> name = CidrTestUtil.extractGoogleTestName((OCStructSymbol) owner);
+ if (name != null) {
+ return createFromClassAndMethod(struct, name.first, name.second);
+ }
+ return createFromClass(
+ struct, ((OCStructSymbol) owner).getQualifiedName().getName());
+ }
+ }
+ }
+ }
+
+ // if we're still here, let's test for a macro and, as a last resort, a file.
+ parent = PsiTreeUtil.getNonStrictParentOfType(element, OCMacroCall.class, OCFile.class);
+ if (parent instanceof OCMacroCall) {
+ OCMacroCall gtestMacro = CidrTestUtil.findGoogleTestMacros(parent);
+ if (gtestMacro != null) {
+ List<OCMacroCallArgument> arguments = gtestMacro.getArguments();
+ if (arguments.size() >= 2) {
+ OCMacroCallArgument suiteArg = arguments.get(0);
+ OCMacroCallArgument testArg = arguments.get(1);
+
+ // if the element is the first argument of macro call,
+ // then running entire suite, otherwise only a current test
+ boolean isSuite =
+ isFirstArgument(PsiTreeUtil.getParentOfType(element, OCMacroCallArgument.class))
+ || isFirstArgument(element.getPrevSibling());
+ String suiteName = CidrTestUtil.extractArgumentValue(suiteArg);
+ String testName = CidrTestUtil.extractArgumentValue(testArg);
+ OCStructSymbol symbol =
+ CidrTestUtil.findGoogleTestSymbol(element.getProject(), suiteName, testName);
+ if (symbol != null) {
+ OCStruct targetElement = (OCStruct) symbol.locateDefinition();
+ return createFromClassAndMethod(
+ targetElement, suiteName, isSuite ? null : testName);
+ }
+ }
+ }
+ Couple<String> suite = CidrTestUtil.extractFullSuiteNameFromMacro(parent);
+ if (suite != null) {
+ Collection<OCStructSymbol> res =
+ CidrTestUtil.findGoogleTestSymbolsForSuiteRandomly(
+ element.getProject(), suite.first, true);
+ if (res.size() != 0) {
+ OCStruct struct = (OCStruct) res.iterator().next().locateDefinition();
+ return createFromClassAndMethod(struct, suite.first, null);
+ }
+ }
+ } else if (parent instanceof OCFile) {
+ return createFromFile(parent);
+ }
+ return null;
+ }
+
+ private static boolean isFirstArgument(@Nullable PsiElement element) {
+ OCMacroCall macroCall = PsiTreeUtil.getParentOfType(element, OCMacroCall.class);
+ if (macroCall != null) {
+ List<OCMacroCallArgument> arguments = macroCall.getArguments();
+ return arguments.size() > 0 && arguments.get(0).equals(element);
+ }
+ return false;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/plugin/ClwbSpecificInitializer.java b/clwb/src/com/google/idea/blaze/plugin/ClwbSpecificInitializer.java
index 4a3445e..086bbbf 100644
--- a/clwb/src/com/google/idea/blaze/plugin/ClwbSpecificInitializer.java
+++ b/clwb/src/com/google/idea/blaze/plugin/ClwbSpecificInitializer.java
@@ -16,12 +16,8 @@
package com.google.idea.blaze.plugin;
import com.google.idea.blaze.base.plugin.BlazeActionRemover;
+import com.google.idea.sdkcompat.clion.CMakeActionList;
import com.intellij.openapi.components.ApplicationComponent;
-import com.jetbrains.cidr.cpp.cmake.actions.ChangeCMakeProjectContentRootAction;
-import com.jetbrains.cidr.cpp.cmake.actions.DropCMakeCacheAction;
-import com.jetbrains.cidr.cpp.cmake.actions.OpenCMakeSettingsAction;
-import com.jetbrains.cidr.cpp.cmake.actions.ReloadCMakeProjectAction;
-import com.jetbrains.cidr.cpp.cmake.actions.ToggleCMakeAutoReloadAction;
/** Runs on startup. */
public class ClwbSpecificInitializer extends ApplicationComponent.Adapter {
@@ -33,12 +29,8 @@
// The original actions will be visible only on plain IDEA projects.
private static void hideCMakeActions() {
- BlazeActionRemover.hideAction(ChangeCMakeProjectContentRootAction.ID);
- BlazeActionRemover.hideAction(DropCMakeCacheAction.ID);
- BlazeActionRemover.hideAction(OpenCMakeSettingsAction.ID);
- BlazeActionRemover.hideAction(ReloadCMakeProjectAction.ID);
- BlazeActionRemover.hideAction(ToggleCMakeAutoReloadAction.ID);
- // 'CMake' > 'Show Generated CMake Files' action
- BlazeActionRemover.hideAction("CMake.ShowGeneratedDir");
+ for (String actionId : CMakeActionList.CMAKE_ACTION_IDS) {
+ BlazeActionRemover.hideAction(actionId);
+ }
}
}
diff --git a/common/actionhelper/src/com/google/idea/common/actionhelper/ActionPresentationHelper.java b/common/actionhelper/src/com/google/idea/common/actionhelper/ActionPresentationHelper.java
index 69c5e1e..c90dd03 100644
--- a/common/actionhelper/src/com/google/idea/common/actionhelper/ActionPresentationHelper.java
+++ b/common/actionhelper/src/com/google/idea/common/actionhelper/ActionPresentationHelper.java
@@ -15,6 +15,7 @@
*/
package com.google.idea.common.actionhelper;
+import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.vfs.VirtualFile;
@@ -24,13 +25,14 @@
/** Helps setting the presentation enabled/visible/text states. */
public class ActionPresentationHelper {
- private final Presentation presentation;
+ private final AnActionEvent event;
private boolean enabled = true;
private boolean visible = true;
private boolean disableWithoutSubject;
private boolean hasSubject;
private String text;
private String subjectText;
+ private boolean hideInContextMenuIfDisabled;
/** Converts a subject to a string */
@FunctionalInterface
@@ -38,12 +40,12 @@
String subjectToString(T subject);
}
- private ActionPresentationHelper(Presentation presentation) {
- this.presentation = presentation;
+ private ActionPresentationHelper(AnActionEvent event) {
+ this.event = event;
}
- public static ActionPresentationHelper of(AnActionEvent e) {
- return new ActionPresentationHelper(e.getPresentation());
+ public static ActionPresentationHelper of(AnActionEvent event) {
+ return new ActionPresentationHelper(event);
}
/** Disables the action if the condition is true. */
@@ -58,6 +60,11 @@
return this;
}
+ public ActionPresentationHelper hideInContextMenuIfDisabled() {
+ this.hideInContextMenuIfDisabled = true;
+ return this;
+ }
+
/** Disables the action if no subject has been provided. */
public ActionPresentationHelper disableWithoutSubject() {
this.disableWithoutSubject = true;
@@ -164,6 +171,12 @@
if (disableWithoutSubject) {
enabled = enabled && hasSubject;
}
+ boolean visible = this.visible;
+ if (hideInContextMenuIfDisabled && !enabled && ActionPlaces.isPopupPlace(event.getPlace())) {
+ visible = false;
+ }
+
+ Presentation presentation = event.getPresentation();
presentation.setEnabled(enabled);
presentation.setVisible(visible);
diff --git a/common/experiments/src/com/google/idea/common/experiments/WebExperimentSyncer.java b/common/experiments/src/com/google/idea/common/experiments/WebExperimentSyncer.java
index 464a62d..43ab2b4 100644
--- a/common/experiments/src/com/google/idea/common/experiments/WebExperimentSyncer.java
+++ b/common/experiments/src/com/google/idea/common/experiments/WebExperimentSyncer.java
@@ -115,7 +115,7 @@
logger.debug("About to fetch experiments.");
return HttpRequests.request(
System.getProperty(EXPERIMENTS_URL_PROPERTY, DEFAULT_EXPERIMENT_URL) + pluginName)
- .readString(null /* progress indicator */);
+ .readString(/* progress indicator */ null);
}
}
@@ -144,10 +144,10 @@
setExperimentValues(mapBuilder);
logger.debug("Successfully fetched experiments: " + getExperimentValues());
- scheduleNextRefresh(true /* refreshWasSuccessful */);
+ scheduleNextRefresh(/* refreshWasSuccessful */ true);
} catch (InterruptedException | ExecutionException | RuntimeException e) {
logger.debug("Error fetching experiments", e);
- scheduleNextRefresh(false /* refreshWasSuccessful */);
+ scheduleNextRefresh(/* refreshWasSuccessful */ false);
}
}
}
diff --git a/cpp/src/com/google/idea/blaze/cpp/BlazeCWorkspace.java b/cpp/src/com/google/idea/blaze/cpp/BlazeCWorkspace.java
index abcb294..c0f5b94 100644
--- a/cpp/src/com/google/idea/blaze/cpp/BlazeCWorkspace.java
+++ b/cpp/src/com/google/idea/blaze/cpp/BlazeCWorkspace.java
@@ -19,37 +19,26 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.scope.BlazeContext;
-import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.sdkcompat.cidr.OCWorkspaceAdapter;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.cidr.lang.symbols.OCSymbol;
import com.jetbrains.cidr.lang.workspace.OCResolveConfiguration;
-import com.jetbrains.cidr.lang.workspace.OCWorkspace;
-import com.jetbrains.cidr.lang.workspace.OCWorkspaceModificationTrackers;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
/** Main entry point for C/CPP configuration data. */
-public final class BlazeCWorkspace implements OCWorkspace {
+public final class BlazeCWorkspace extends OCWorkspaceAdapter {
private static final Logger logger = Logger.getInstance(BlazeCWorkspace.class);
- @Nullable private final Project project;
- @Nullable private final OCWorkspaceModificationTrackers modTrackers;
-
- @Nullable private BlazeConfigurationResolver configurationResolver;
+ private final BlazeConfigurationResolver configurationResolver;
private BlazeCWorkspace(Project project) {
- if (Blaze.isBlazeProject(project)) {
- this.project = project;
- this.modTrackers = new OCWorkspaceModificationTrackers(project);
- this.configurationResolver = new BlazeConfigurationResolver(project);
- } else {
- this.project = null;
- this.modTrackers = null;
- }
+ super(project);
+ this.configurationResolver = new BlazeConfigurationResolver(project);
}
public static BlazeCWorkspace getInstance(Project project) {
@@ -57,13 +46,8 @@
}
public void update(BlazeContext context, BlazeProjectData blazeProjectData) {
- logger.assertTrue(project != null);
- logger.assertTrue(modTrackers != null);
- logger.assertTrue(configurationResolver != null);
-
- long start = System.currentTimeMillis();
-
// Non-incremental update to our c configurations.
+ long start = System.currentTimeMillis();
configurationResolver.update(context, blazeProjectData);
long end = System.currentTimeMillis();
@@ -97,29 +81,15 @@
return false;
}
- @Nullable
- @Override
- public OCResolveConfiguration getSelectedResolveConfiguration() {
- return null;
- }
-
- @Override
- public OCWorkspaceModificationTrackers getModificationTrackers() {
- logger.assertTrue(modTrackers != null);
- return modTrackers;
- }
-
@Override
public List<? extends OCResolveConfiguration> getConfigurations() {
- return configurationResolver == null
- ? ImmutableList.of()
- : configurationResolver.getAllConfigurations();
+ return configurationResolver.getAllConfigurations();
}
@Override
public List<? extends OCResolveConfiguration> getConfigurationsForFile(
@Nullable VirtualFile sourceFile) {
- if (sourceFile == null || !sourceFile.isValid() || configurationResolver == null) {
+ if (sourceFile == null || !sourceFile.isValid()) {
return ImmutableList.of();
}
OCResolveConfiguration config = configurationResolver.getConfigurationForFile(sourceFile);
diff --git a/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java b/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
index 5e6e8b9..f4b5cd6 100644
--- a/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
+++ b/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
@@ -34,11 +34,13 @@
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.Scope;
import com.google.idea.blaze.base.scope.ScopedFunction;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.scope.scopes.TimingScope;
+import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.sync.workspace.ExecutionRootPathResolver;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.google.idea.blaze.base.targetmaps.SourceToTargetMap;
@@ -91,7 +93,7 @@
buildBlazeConfigurationMap(context, blazeProjectData, toolchainLookupMap, headerRoots);
}
- private static ImmutableMap<File, VirtualFile> collectHeaderRoots(
+ private ImmutableMap<File, VirtualFile> collectHeaderRoots(
BlazeContext parentContext,
BlazeProjectData blazeProjectData,
ImmutableMap<TargetKey, CToolchainIdeInfo> toolchainLookupMap) {
@@ -107,10 +109,14 @@
});
}
- private static ImmutableMap<File, VirtualFile> doCollectHeaderRoots(
+ private ImmutableMap<File, VirtualFile> doCollectHeaderRoots(
BlazeContext context, BlazeProjectData projectData, Set<ExecutionRootPath> rootPaths) {
ExecutionRootPathResolver pathResolver =
- new ExecutionRootPathResolver(projectData.blazeRoots, projectData.workspacePathResolver);
+ new ExecutionRootPathResolver(
+ Blaze.getBuildSystem(project),
+ WorkspaceRoot.fromProject(project),
+ projectData.blazeRoots.executionRoot,
+ projectData.workspacePathResolver);
ConcurrentMap<File, VirtualFile> rootsMap = Maps.newConcurrentMap();
List<ListenableFuture<Void>> futures = Lists.newArrayListWithCapacity(rootPaths.size());
for (ExecutionRootPath path : rootPaths) {
@@ -253,7 +259,10 @@
BlazeResolveConfiguration.createConfigurationForTarget(
project,
new ExecutionRootPathResolver(
- blazeProjectData.blazeRoots, blazeProjectData.workspacePathResolver),
+ Blaze.getBuildSystem(project),
+ WorkspaceRoot.fromProject(project),
+ blazeProjectData.blazeRoots.executionRoot,
+ blazeProjectData.workspacePathResolver),
blazeProjectData.workspacePathResolver,
headerRoots,
blazeProjectData.targetMap.get(targetKey),
diff --git a/cpp/src/com/google/idea/blaze/cpp/BlazeCppSymbolRebuildSyncListener.java b/cpp/src/com/google/idea/blaze/cpp/BlazeCppSymbolRebuildSyncListener.java
index 07b1743..fb9e190 100644
--- a/cpp/src/com/google/idea/blaze/cpp/BlazeCppSymbolRebuildSyncListener.java
+++ b/cpp/src/com/google/idea/blaze/cpp/BlazeCppSymbolRebuildSyncListener.java
@@ -21,12 +21,12 @@
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.BlazeSyncParams.SyncMode;
import com.google.idea.blaze.base.sync.SyncListener;
+import com.google.idea.sdkcompat.cidr.OCWorkspaceModificationTrackersCompatUtils;
import com.google.idea.sdkcompat.transactions.Transactions;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.jetbrains.cidr.lang.workspace.OCWorkspace;
import com.jetbrains.cidr.lang.workspace.OCWorkspaceManager;
-import com.jetbrains.cidr.lang.workspace.OCWorkspaceModificationTrackers;
/** Runs after sync, triggering a rebuild of the symbol tables. */
public class BlazeCppSymbolRebuildSyncListener extends SyncListener.Adapter {
@@ -45,20 +45,16 @@
if (!(workspace instanceof BlazeCWorkspace)) {
return;
}
- rebuildSymbolTables((BlazeCWorkspace) workspace);
+ rebuildSymbolTables(project);
}
- private static void rebuildSymbolTables(BlazeCWorkspace workspace) {
- OCWorkspaceModificationTrackers modTrackers = workspace.getModificationTrackers();
+ private static void rebuildSymbolTables(Project project) {
Transactions.submitTransactionAndWait(
() ->
ApplicationManager.getApplication()
.runWriteAction(
- () -> {
- modTrackers.getProjectFilesListTracker().incModificationCount();
- modTrackers.getSourceFilesListTracker().incModificationCount();
- modTrackers.getBuildConfigurationChangesTracker().incModificationCount();
- modTrackers.getBuildSettingsChangesTracker().incModificationCount();
- }));
+ () ->
+ OCWorkspaceModificationTrackersCompatUtils.incrementModificationCounts(
+ project)));
}
}
diff --git a/ijwb/src/com/google/idea/blaze/ijwb/typescript/BlazeTypescriptSyncPlugin.java b/ijwb/src/com/google/idea/blaze/ijwb/typescript/BlazeTypescriptSyncPlugin.java
index e013c14..d6ab6a7 100644
--- a/ijwb/src/com/google/idea/blaze/ijwb/typescript/BlazeTypescriptSyncPlugin.java
+++ b/ijwb/src/com/google/idea/blaze/ijwb/typescript/BlazeTypescriptSyncPlugin.java
@@ -96,7 +96,9 @@
childContext.output(new StatusOutput("Updating tsconfig..."));
BlazeCommand command =
- BlazeCommand.builder(Blaze.getBuildSystem(project), BlazeCommandName.RUN)
+ BlazeCommand.builder(
+ Blaze.getBuildSystemProvider(project).getSyncBinaryPath(),
+ BlazeCommandName.RUN)
.addTargets(tsConfig)
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
.build();
diff --git a/intellij_platform_sdk/BUILD b/intellij_platform_sdk/BUILD
index 9edcbbf..88f4b35 100644
--- a/intellij_platform_sdk/BUILD
+++ b/intellij_platform_sdk/BUILD
@@ -70,6 +70,14 @@
},
)
+# Android Studio 2.3.0.6
+config_setting(
+ name = "android-studio-2.3.0.6",
+ values = {
+ "define": "ij_product=android-studio-2.3.0.6",
+ },
+)
+
config_setting(
name = "clion-latest",
values = {
@@ -201,6 +209,9 @@
"android-studio-2.3.0.4": [
"missing/tests/com/jetbrains/cidr/modulemap/resolve/MockModuleMapManagerImpl.java",
],
+ "android-studio-2.3.0.6": [
+ "missing/tests/com/jetbrains/cidr/modulemap/resolve/MockModuleMapManagerImpl.java",
+ ],
"default": [],
}) + ["missing/src/dummy/pkg/DummyClassToAvoidAnEmptyJavaLibrary.java"],
tags = ["intellij-missing-test-classes"],
diff --git a/intellij_platform_sdk/build_defs.bzl b/intellij_platform_sdk/build_defs.bzl
index 6fa3efb..f833101 100644
--- a/intellij_platform_sdk/build_defs.bzl
+++ b/intellij_platform_sdk/build_defs.bzl
@@ -29,6 +29,10 @@
ide="android-studio",
directory="android_studio_2_3_0_4",
),
+ "android-studio-2.3.0.6": struct(
+ ide="android-studio",
+ directory="android_studio_2_3_0_6",
+ ),
"clion-162.1967.7": struct(
ide="clion",
directory="CL_162_1967_7",
@@ -119,9 +123,9 @@
),
)
"""
- intellij = intellij or default
- android_studio = android_studio or default
- clion = clion or default
+ intellij = intellij if intellij != None else default
+ android_studio = android_studio if android_studio != None else default
+ clion = clion if clion != None else default
ide_to_value = {
"intellij" : intellij,
diff --git a/java/BUILD b/java/BUILD
index ac9f772..20786ea 100644
--- a/java/BUILD
+++ b/java/BUILD
@@ -10,7 +10,7 @@
"//common/experiments",
"//intellij_platform_sdk:junit",
"//intellij_platform_sdk:plugin_api",
- "//proto_deps",
+ "//proto:proto_deps",
"//sdkcompat",
"@jsr305_annotations//jar",
],
@@ -71,7 +71,7 @@
"//common/experiments",
"//common/experiments:unit_test_utils",
"//intellij_platform_sdk:plugin_api_for_tests",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
"@junit//jar",
],
diff --git a/java/src/META-INF/blaze-java.xml b/java/src/META-INF/blaze-java.xml
index e46fa6c..bf8b3cf 100644
--- a/java/src/META-INF/blaze-java.xml
+++ b/java/src/META-INF/blaze-java.xml
@@ -84,6 +84,12 @@
<runConfigurationProducer
implementation="com.google.idea.blaze.java.run.producers.BlazeJavaTestMethodConfigurationProducer"
order="first"/>
+ <runConfigurationProducer
+ implementation="com.google.idea.blaze.java.run.producers.BlazeJavaAbstractTestCaseConfigurationProducer"
+ order="first"/>
+ <runConfigurationProducer
+ implementation="com.google.idea.blaze.java.run.producers.MultipleJavaClassesTestConfigurationProducer"
+ order="first"/>
<projectViewNodeDecorator implementation="com.google.idea.blaze.java.syncstatus.BlazeJavaSyncStatusClassNodeDecorator"/>
<editorTabColorProvider implementation="com.google.idea.blaze.java.syncstatus.BlazeJavaSyncStatusEditorTabColorProvider"/>
<editorTabTitleProvider implementation="com.google.idea.blaze.java.syncstatus.BlazeJavaSyncStatusEditorTabTitleProvider"/>
diff --git a/java/src/com/google/idea/blaze/java/lang/build/BuildFileSafeDeleteProcessor.java b/java/src/com/google/idea/blaze/java/lang/build/BuildFileSafeDeleteProcessor.java
index 390ce7b..63b2017 100644
--- a/java/src/com/google/idea/blaze/java/lang/build/BuildFileSafeDeleteProcessor.java
+++ b/java/src/com/google/idea/blaze/java/lang/build/BuildFileSafeDeleteProcessor.java
@@ -30,8 +30,8 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* Removes glob references which don't refer directly to the item(s) being deleted (b/28979434)
diff --git a/java/src/com/google/idea/blaze/java/libraries/LibraryActionHelper.java b/java/src/com/google/idea/blaze/java/libraries/LibraryActionHelper.java
index 35a00ca..cc50651 100644
--- a/java/src/com/google/idea/blaze/java/libraries/LibraryActionHelper.java
+++ b/java/src/com/google/idea/blaze/java/libraries/LibraryActionHelper.java
@@ -31,8 +31,8 @@
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.Navigatable;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
class LibraryActionHelper {
diff --git a/java/src/com/google/idea/blaze/java/run/BlazeJavaRunProfileState.java b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunProfileState.java
index 6175856..b047b41 100644
--- a/java/src/com/google/idea/blaze/java/run/BlazeJavaRunProfileState.java
+++ b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunProfileState.java
@@ -40,7 +40,6 @@
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
-import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
@@ -65,9 +64,6 @@
*/
final class BlazeJavaRunProfileState extends CommandLineState implements RemoteState {
- private static final BoolExperiment smRunnerUiEnabled =
- new BoolExperiment("use.smrunner.ui.java", true);
-
// Blaze seems to always use this port for --java_debug.
// TODO(joshgiles): Look at manually identifying and setting port.
private static final int DEBUG_PORT = 5005;
@@ -155,9 +151,6 @@
}
private boolean useTestUi() {
- if (!smRunnerUiEnabled.getValue()) {
- return false;
- }
BlazeCommandRunConfigurationCommonState state =
configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
return state != null
@@ -171,10 +164,10 @@
return null;
}
return new RemoteConnection(
- true /* useSockets */,
+ /* useSockets */ true,
DEBUG_HOST_NAME,
Integer.toString(DEBUG_PORT),
- false /* serverMode */);
+ /* serverMode */ false);
}
@VisibleForTesting
@@ -189,11 +182,15 @@
configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
assert handlerState != null;
+ String binaryPath =
+ handlerState.getBlazeBinary() != null
+ ? handlerState.getBlazeBinary()
+ : Blaze.getBuildSystemProvider(project).getBinaryPath();
+
BlazeCommandName blazeCommand = handlerState.getCommand();
assert blazeCommand != null;
BlazeCommand.Builder command =
- BlazeCommand.builder(Blaze.getBuildSystem(project), blazeCommand)
- .setBlazeBinary(handlerState.getBlazeBinary())
+ BlazeCommand.builder(binaryPath, blazeCommand)
.addTargets(configuration.getTarget())
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
.addBlazeFlags(extraBlazeFlags)
@@ -210,9 +207,6 @@
} else {
boolean runDistributed = handlerState.getRunOnDistributedExecutor();
command.addBlazeFlags(DistributedExecutorSupport.getBlazeFlags(project, runDistributed));
- if (!runDistributed) {
- command.addBlazeFlags(BlazeFlags.TEST_OUTPUT_STREAMED);
- }
}
command.addExeFlags(handlerState.getExeFlags());
diff --git a/java/src/com/google/idea/blaze/java/run/BlazeJavaTestEventsHandler.java b/java/src/com/google/idea/blaze/java/run/BlazeJavaTestEventsHandler.java
index 4a1024f..8091b51 100644
--- a/java/src/com/google/idea/blaze/java/run/BlazeJavaTestEventsHandler.java
+++ b/java/src/com/google/idea/blaze/java/run/BlazeJavaTestEventsHandler.java
@@ -47,13 +47,13 @@
/** Overridden to support parameterized tests, which use nested test_suite XML elements. */
@Override
- public boolean ignoreSuite(TestSuite suite) {
+ public boolean ignoreSuite(@Nullable Kind kind, TestSuite suite) {
if (suite.testSuites.isEmpty()) {
return false;
}
for (TestSuite child : suite.testSuites) {
// target/class names are fully-qualified; unqualified names denote parameterized methods
- if (!child.name.contains(".")) {
+ if (child.name != null && !child.name.contains(".")) {
return false;
}
}
diff --git a/java/src/com/google/idea/blaze/java/run/RunUtil.java b/java/src/com/google/idea/blaze/java/run/RunUtil.java
index 724d72f..2f36e20 100644
--- a/java/src/com/google/idea/blaze/java/run/RunUtil.java
+++ b/java/src/com/google/idea/blaze/java/run/RunUtil.java
@@ -16,7 +16,7 @@
package com.google.idea.blaze.java.run;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
-import com.google.idea.blaze.base.ideinfo.TestIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TestIdeInfo.TestSize;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.run.TestTargetFinder;
import com.google.idea.blaze.base.run.TestTargetHeuristic;
@@ -27,8 +27,7 @@
import com.intellij.psi.PsiFile;
import java.io.File;
import java.util.Collection;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Utility methods for finding rules and Android facets. */
public final class RunUtil {
@@ -40,18 +39,16 @@
* containing rules, the first rule sorted alphabetically by label.
*/
@Nullable
- public static TargetIdeInfo targetForTestClass(
- @NotNull Project project,
- @NotNull PsiClass testClass,
- @Nullable TestIdeInfo.TestSize testSize) {
+ public static TargetIdeInfo targetForTestClass(PsiClass testClass, @Nullable TestSize testSize) {
File testFile = getFileForClass(testClass);
if (testFile == null) {
return null;
}
+ Project project = testClass.getProject();
Collection<TargetIdeInfo> targets =
TestTargetFinder.getInstance(project).testTargetsForSourceFile(testFile);
Label testLabel =
- TestTargetHeuristic.chooseTestTargetForSourceFile(testFile, targets, testSize);
+ TestTargetHeuristic.chooseTestTargetForSourceFile(project, testFile, targets, testSize);
if (testLabel == null) {
return null;
}
@@ -64,7 +61,7 @@
* memory.
*/
@Nullable
- public static File getFileForClass(@NotNull PsiClass aClass) {
+ public static File getFileForClass(PsiClass aClass) {
PsiFile containingFile = aClass.getContainingFile();
if (containingFile == null) {
return null;
diff --git a/java/src/com/google/idea/blaze/java/run/producers/BlazeJUnitTestFilterFlags.java b/java/src/com/google/idea/blaze/java/run/producers/BlazeJUnitTestFilterFlags.java
index 4ee0508..8c9963d 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/BlazeJUnitTestFilterFlags.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/BlazeJUnitTestFilterFlags.java
@@ -105,10 +105,12 @@
String filter =
testFilterForClassAndMethods(
entry.getKey(), version, extractMethodFilters(entry.getValue()));
- if (filter != null) {
- classFilters.add(filter);
+ if (filter == null) {
+ return null;
}
+ classFilters.add(filter);
}
+ classFilters.sort(String::compareTo);
return version == JUnitVersion.JUNIT_4
? String.join("|", classFilters)
: String.join(",", classFilters);
diff --git a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaAbstractTestCaseConfigurationProducer.java b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaAbstractTestCaseConfigurationProducer.java
new file mode 100644
index 0000000..7e6ca2f
--- /dev/null
+++ b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaAbstractTestCaseConfigurationProducer.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2017 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.java.run.producers;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TestIdeInfo;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
+import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
+import com.google.idea.blaze.base.run.producers.BlazeRunConfigurationProducer;
+import com.google.idea.blaze.base.run.smrunner.SmRunnerUtils;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.java.run.RunUtil;
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.execution.JavaExecutionUtil;
+import com.intellij.execution.Location;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.execution.junit.JUnitUtil;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiModifier;
+import com.intellij.psi.util.PsiTreeUtil;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/** Producer for abstract test classes/methods. */
+public class BlazeJavaAbstractTestCaseConfigurationProducer
+ extends BlazeRunConfigurationProducer<BlazeCommandRunConfiguration> {
+
+ private static class AbstractTestLocation {
+ private final PsiClass abstractClass;
+ @Nullable private final PsiMethod method;
+
+ private AbstractTestLocation(PsiClass abstractClass, @Nullable PsiMethod method) {
+ this.abstractClass = abstractClass;
+ this.method = method;
+ }
+ }
+
+ public BlazeJavaAbstractTestCaseConfigurationProducer() {
+ super(BlazeCommandRunConfigurationType.getInstance());
+ }
+
+ @Override
+ protected boolean doSetupConfigFromContext(
+ BlazeCommandRunConfiguration configuration,
+ ConfigurationContext context,
+ Ref<PsiElement> sourceElement) {
+ AbstractTestLocation location = getAbstractLocation(context);
+ if (location == null) {
+ return false;
+ }
+ sourceElement.set(location.method != null ? location.method : location.abstractClass);
+ configuration.setName(configName(location.abstractClass, location.method));
+ configuration.setNameChangedByUser(true);
+ return true;
+ }
+
+ @Nullable
+ private static AbstractTestLocation getAbstractLocation(ConfigurationContext context) {
+ if (!SmRunnerUtils.getSelectedSmRunnerTreeElements(context).isEmpty()) {
+ // handled by a different producer
+ return null;
+ }
+ PsiMethod method = getTestMethod(context);
+ if (method != null) {
+ PsiClass psiClass = method.getContainingClass();
+ return isAbstractClass(psiClass) ? new AbstractTestLocation(psiClass, method) : null;
+ }
+ Location location = context.getLocation();
+ if (location == null) {
+ return null;
+ }
+ location = JavaExecutionUtil.stepIntoSingleClass(location);
+ PsiClass psiClass =
+ PsiTreeUtil.getParentOfType(location.getPsiElement(), PsiClass.class, false);
+ if (!isAbstractClass(psiClass)) {
+ return null;
+ }
+ for (PsiClass subclass : SubclassTestChooser.findTestSubclasses(psiClass)) {
+ if (JUnitUtil.isTestClass(subclass)) {
+ return new AbstractTestLocation(psiClass, null);
+ }
+ }
+ return null;
+ }
+
+ private static PsiMethod getTestMethod(ConfigurationContext context) {
+ PsiElement psi = context.getPsiLocation();
+ if (psi instanceof PsiMethod
+ && AnnotationUtil.isAnnotated((PsiMethod) psi, JUnitUtil.TEST_ANNOTATION, false)) {
+ return (PsiMethod) psi;
+ }
+ List<PsiMethod> selectedMethods = TestMethodSelectionUtil.getSelectedMethods(context);
+ return selectedMethods != null && selectedMethods.size() == 1 ? selectedMethods.get(0) : null;
+ }
+
+ private static boolean isAbstractClass(@Nullable PsiClass psiClass) {
+ return psiClass != null && psiClass.hasModifierProperty(PsiModifier.ABSTRACT);
+ }
+
+ @Override
+ protected boolean doIsConfigFromContext(
+ BlazeCommandRunConfiguration configuration, ConfigurationContext context) {
+ // this is an intermediate type -- when it's fully instantiated (via 'onFirstRun') it will be
+ // recognized by a different producer.
+ return false;
+ }
+
+ @Override
+ public void onFirstRun(
+ ConfigurationFromContext configuration,
+ ConfigurationContext context,
+ Runnable startRunnable) {
+ chooseSubclass(configuration, context, startRunnable);
+ }
+
+ @VisibleForTesting
+ static void chooseSubclass(
+ ConfigurationFromContext configuration,
+ ConfigurationContext context,
+ Runnable startRunnable) {
+ RunConfiguration config = configuration.getConfiguration();
+ if (!(config instanceof BlazeCommandRunConfiguration)) {
+ return;
+ }
+ AbstractTestLocation location = locationFromConfiguration(configuration);
+ if (location == null) {
+ return;
+ }
+ SubclassTestChooser.chooseSubclass(
+ context,
+ location.abstractClass,
+ (psiClass) -> {
+ if (psiClass != null) {
+ setupContext((BlazeCommandRunConfiguration) config, psiClass, location.method);
+ }
+ startRunnable.run();
+ });
+ }
+
+ @Nullable
+ private static AbstractTestLocation locationFromConfiguration(
+ ConfigurationFromContext configuration) {
+ PsiElement element = configuration.getSourceElement();
+ PsiMethod method = null;
+ PsiClass psiClass = null;
+ if (element instanceof PsiMethod) {
+ method = (PsiMethod) element;
+ psiClass = method.getContainingClass();
+ } else if (element instanceof PsiClass) {
+ psiClass = (PsiClass) element;
+ }
+
+ return isAbstractClass(psiClass) ? new AbstractTestLocation(psiClass, method) : null;
+ }
+
+ private static void setupContext(
+ BlazeCommandRunConfiguration configuration, PsiClass subClass, @Nullable PsiMethod method) {
+ TestIdeInfo.TestSize testSize =
+ method != null
+ ? TestSizeAnnotationMap.getTestSize(method)
+ : TestSizeAnnotationMap.getTestSize(subClass);
+ TargetIdeInfo target = RunUtil.targetForTestClass(subClass, testSize);
+ if (target == null) {
+ return;
+ }
+ configuration.setTarget(target.key.label);
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
+ return;
+ }
+ handlerState.setCommand(BlazeCommandName.TEST);
+
+ // remove old test filter flag if present
+ List<String> flags = new ArrayList<>(handlerState.getBlazeFlags());
+ flags.removeIf((flag) -> flag.startsWith(BlazeFlags.TEST_FILTER));
+
+ String testFilter =
+ BlazeJUnitTestFilterFlags.testFilterForClassAndMethods(
+ subClass, method == null ? ImmutableList.of() : ImmutableList.of(method));
+ if (testFilter == null) {
+ return;
+ }
+ flags.add(BlazeFlags.TEST_FILTER + "=" + testFilter);
+ handlerState.setBlazeFlags(flags);
+
+ BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration);
+ nameBuilder.setTargetString(configName(subClass, method));
+ configuration.setName(nameBuilder.build());
+ configuration.setNameChangedByUser(true); // don't revert to generated name
+ }
+
+ private static String configName(PsiClass psiClass, @Nullable PsiMethod method) {
+ return method == null
+ ? psiClass.getName()
+ : String.format("%s.%s", psiClass.getName(), method.getName());
+ }
+}
diff --git a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassRunConfigurationProducer.java b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassRunConfigurationProducer.java
index b90826a..73827e8 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassRunConfigurationProducer.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassRunConfigurationProducer.java
@@ -41,7 +41,7 @@
import java.io.File;
import java.util.Collection;
import java.util.Objects;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Creates run configurations for Java main classes sourced by java_binary targets. */
public class BlazeJavaMainClassRunConfigurationProducer
diff --git a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducer.java b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducer.java
index 7d9a20f..20d6b74 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducer.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducer.java
@@ -79,7 +79,7 @@
sourceElement.set(testClass);
TestIdeInfo.TestSize testSize = TestSizeAnnotationMap.getTestSize(testClass);
- TargetIdeInfo target = RunUtil.targetForTestClass(context.getProject(), testClass, testSize);
+ TargetIdeInfo target = RunUtil.targetForTestClass(testClass, testSize);
if (target == null) {
return false;
}
diff --git a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducer.java b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducer.java
index e0453d1..071d5fb 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducer.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducer.java
@@ -80,8 +80,7 @@
sourceElement.set(methodInfo.firstMethod);
TestIdeInfo.TestSize testSize = TestSizeAnnotationMap.getTestSize(methodInfo.firstMethod);
- TargetIdeInfo target =
- RunUtil.targetForTestClass(context.getProject(), methodInfo.containingClass, testSize);
+ TargetIdeInfo target = RunUtil.targetForTestClass(methodInfo.containingClass, testSize);
if (target == null) {
return false;
}
diff --git a/java/src/com/google/idea/blaze/java/run/producers/MultipleJavaClassesTestConfigurationProducer.java b/java/src/com/google/idea/blaze/java/run/producers/MultipleJavaClassesTestConfigurationProducer.java
new file mode 100644
index 0000000..df62114
--- /dev/null
+++ b/java/src/com/google/idea/blaze/java/run/producers/MultipleJavaClassesTestConfigurationProducer.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2017 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.java.run.producers;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TestIdeInfo;
+import com.google.idea.blaze.base.lang.buildfile.search.BlazePackage;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
+import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
+import com.google.idea.blaze.base.run.producers.BlazeRunConfigurationProducer;
+import com.google.idea.blaze.base.run.smrunner.SmRunnerUtils;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.java.run.RunUtil;
+import com.intellij.execution.Location;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.junit.JUnitUtil;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.JavaDirectoryService;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiModifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import javax.annotation.Nullable;
+
+/**
+ * Runs tests in all selected java classes (or all classes below selected directory). Ignores
+ * classes spread across multiple test targets.
+ */
+public class MultipleJavaClassesTestConfigurationProducer
+ extends BlazeRunConfigurationProducer<BlazeCommandRunConfiguration> {
+
+ public MultipleJavaClassesTestConfigurationProducer() {
+ super(BlazeCommandRunConfigurationType.getInstance());
+ }
+
+ @Override
+ protected boolean doSetupConfigFromContext(
+ BlazeCommandRunConfiguration configuration,
+ ConfigurationContext context,
+ Ref<PsiElement> sourceElement) {
+ TestLocation location = getTestLocation(context);
+ if (location == null) {
+ return false;
+ }
+ sourceElement.set(location.psiLocation);
+ configuration.setTarget(location.label);
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
+ return false;
+ }
+ handlerState.setCommand(BlazeCommandName.TEST);
+
+ // remove old test filter flag if present
+ List<String> flags = new ArrayList<>(handlerState.getBlazeFlags());
+ flags.removeIf((flag) -> flag.startsWith(BlazeFlags.TEST_FILTER));
+ if (location.testFilter != null) {
+ flags.add(location.testFilter);
+ }
+ handlerState.setBlazeFlags(flags);
+
+ if (location.description != null) {
+ BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration);
+ nameBuilder.setTargetString(location.description);
+ configuration.setName(nameBuilder.build());
+ configuration.setNameChangedByUser(true); // don't revert to generated name
+ } else {
+ configuration.setGeneratedName();
+ }
+ return true;
+ }
+
+ @Override
+ protected boolean doIsConfigFromContext(
+ BlazeCommandRunConfiguration configuration, ConfigurationContext context) {
+
+ TestLocation location = getTestLocation(context);
+ if (location == null) {
+ return false;
+ }
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
+ return false;
+ }
+ return BlazeCommandName.TEST.equals(handlerState.getCommand())
+ && location.label.equals(configuration.getTarget())
+ && Objects.equals(location.testFilter, handlerState.getTestFilterFlag());
+ }
+
+ @Nullable
+ private static TestLocation getTestLocation(ConfigurationContext context) {
+ if (!SmRunnerUtils.getSelectedSmRunnerTreeElements(context).isEmpty()) {
+ // handled by a different producer
+ return null;
+ }
+ PsiElement location = context.getPsiLocation();
+ if (location instanceof PsiDirectory) {
+ PsiDirectory dir = (PsiDirectory) location;
+ TargetIdeInfo target = getTestTargetIfUnique(dir);
+ return target != null ? TestLocation.fromDirectory(target.key.label, dir) : null;
+ }
+ List<PsiClass> testClasses = selectedTestClasses(context);
+ if (testClasses.size() < 2) {
+ return null;
+ }
+ TargetIdeInfo target = getTestTargetIfUnique(testClasses);
+ return target != null ? TestLocation.fromClasses(target.key.label, testClasses) : null;
+ }
+
+ private static List<PsiClass> selectedTestClasses(ConfigurationContext context) {
+ DataContext dataContext = context.getDataContext();
+ PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
+ if (elements == null) {
+ return ImmutableList.of();
+ }
+ return Arrays.stream(elements)
+ .map(JUnitUtil::getTestClass)
+ .filter(Objects::nonNull)
+ .filter(testClass -> !testClass.hasModifierProperty(PsiModifier.ABSTRACT))
+ .collect(Collectors.toList());
+ }
+
+ @Nullable
+ private static TargetIdeInfo getTestTargetIfUnique(PsiDirectory directory) {
+ if (BlazePackage.hasBlazePackageChild(directory)) {
+ return null;
+ }
+ List<PsiClass> classes = new ArrayList<>();
+ addClassesInDirectory(directory, classes);
+ return getTestTargetIfUnique(classes);
+ }
+
+ private static void addClassesInDirectory(PsiDirectory directory, List<PsiClass> list) {
+ Collections.addAll(list, JavaDirectoryService.getInstance().getClasses(directory));
+ for (PsiDirectory child : directory.getSubdirectories()) {
+ addClassesInDirectory(child, list);
+ }
+ }
+
+ @Nullable
+ private static TargetIdeInfo getTestTargetIfUnique(List<PsiClass> classes) {
+ TargetIdeInfo testTarget = null;
+ for (PsiClass psiClass : classes) {
+ TargetIdeInfo target = testTargetForClass(psiClass);
+ if (target == null) {
+ continue;
+ }
+ if (testTarget != null && testTarget != target) {
+ return null;
+ }
+ testTarget = target;
+ }
+ return testTarget;
+ }
+
+ @Nullable
+ private static TargetIdeInfo testTargetForClass(PsiClass psiClass) {
+ PsiClass testClass = JUnitUtil.getTestClass(psiClass);
+ if (testClass == null || testClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
+ return null;
+ }
+ TestIdeInfo.TestSize testSize = TestSizeAnnotationMap.getTestSize(psiClass);
+ return RunUtil.targetForTestClass(psiClass, testSize);
+ }
+
+ private static class TestLocation {
+ @Nullable
+ static TestLocation fromClasses(Label label, List<PsiClass> classes) {
+ Map<PsiClass, Collection<Location<?>>> methodsPerClass =
+ classes.stream().collect(Collectors.toMap(c -> c, c -> ImmutableList.of()));
+ String filter = BlazeJUnitTestFilterFlags.testFilterForClassesAndMethods(methodsPerClass);
+ if (filter == null) {
+ return null;
+ }
+ String name = classes.get(0).getName();
+ if (classes.size() > 1) {
+ name += String.format(" and %s others", classes.size() - 1);
+ }
+ return new TestLocation(label, classes.get(0), filter, name);
+ }
+
+ @Nullable
+ static TestLocation fromDirectory(Label label, PsiDirectory dir) {
+ String packagePrefix =
+ ProjectFileIndex.SERVICE
+ .getInstance(dir.getProject())
+ .getPackageNameByDirectory(dir.getVirtualFile());
+ if (packagePrefix == null) {
+ return null;
+ }
+ String description =
+ packagePrefix.isEmpty() ? null : String.format("all in directory '%s'", dir.getName());
+ return new TestLocation(label, dir, packagePrefix, description);
+ }
+
+ private final Label label;
+ private final PsiElement psiLocation;
+ @Nullable private final String testFilter;
+ @Nullable private final String description;
+
+ private TestLocation(
+ Label label, PsiElement psiLocation, String testFilter, @Nullable String description) {
+ this.label = label;
+ this.psiLocation = psiLocation;
+ this.testFilter = !testFilter.isEmpty() ? BlazeFlags.TEST_FILTER + "=" + testFilter : null;
+ this.description = description;
+ }
+ }
+}
diff --git a/java/src/com/google/idea/blaze/java/run/producers/NonBlazeProducerSuppressor.java b/java/src/com/google/idea/blaze/java/run/producers/NonBlazeProducerSuppressor.java
index faf3545..3d64ef8 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/NonBlazeProducerSuppressor.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/NonBlazeProducerSuppressor.java
@@ -35,17 +35,18 @@
private static final Collection<Class<? extends RunConfigurationProducer<?>>>
PRODUCERS_TO_SUPPRESS =
ImmutableList.of(
- // JUnit test producers
com.intellij.execution.junit.AllInDirectoryConfigurationProducer.class,
com.intellij.execution.junit.AllInPackageConfigurationProducer.class,
com.intellij.execution.junit.TestClassConfigurationProducer.class,
com.intellij.execution.junit.TestMethodConfigurationProducer.class,
- com.intellij.execution.junit.PatternConfigurationProducer.class);
+ com.intellij.execution.junit.PatternConfigurationProducer.class,
+ com.intellij.execution.application.ApplicationConfigurationProducer.class);
- private static final ImmutableList<String> KOTLIN_JUNIT_PRODUCERS =
+ private static final ImmutableList<String> KOTLIN_PRODUCERS =
ImmutableList.of(
"org.jetbrains.kotlin.idea.run.KotlinJUnitRunConfigurationProducer",
- "org.jetbrains.kotlin.idea.run.KotlinPatternConfigurationProducer");
+ "org.jetbrains.kotlin.idea.run.KotlinPatternConfigurationProducer",
+ "org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer");
private static Collection<Class<? extends RunConfigurationProducer<?>>> getKotlinProducers() {
// rather than compiling against the Kotlin plugin, and including a switch in the our
@@ -55,7 +56,7 @@
return ImmutableList.of();
}
ClassLoader loader = plugin.getPluginClassLoader();
- return KOTLIN_JUNIT_PRODUCERS
+ return KOTLIN_PRODUCERS
.stream()
.map((qualifiedName) -> loadClass(loader, qualifiedName))
.filter(Objects::nonNull)
diff --git a/java/src/com/google/idea/blaze/java/run/producers/ProducerUtils.java b/java/src/com/google/idea/blaze/java/run/producers/ProducerUtils.java
index b1b40ab..e7d809a 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/ProducerUtils.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/ProducerUtils.java
@@ -22,8 +22,8 @@
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import java.util.Iterator;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* Copy of {@link org.jetbrains.plugins.gradle.execution.test.runner.TestRunnerUtils}.
diff --git a/java/src/com/google/idea/blaze/java/run/producers/SubclassTestChooser.java b/java/src/com/google/idea/blaze/java/run/producers/SubclassTestChooser.java
new file mode 100644
index 0000000..1bc5250
--- /dev/null
+++ b/java/src/com/google/idea/blaze/java/run/producers/SubclassTestChooser.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2017 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.java.run.producers;
+
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.junit.JUnitUtil;
+import com.intellij.ide.util.PsiClassListCellRenderer;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.ui.components.JBList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import javax.swing.ListSelectionModel;
+
+/**
+ * Pop up a dialog to choose a child test class. Called when creating a run configuration from an
+ * abstract test class/method.
+ */
+public class SubclassTestChooser {
+
+ static void chooseSubclass(
+ ConfigurationContext context,
+ PsiClass abstractClass,
+ Consumer<PsiClass> callbackOnClassSelection) {
+ List<PsiClass> classes = findTestSubclasses(abstractClass);
+ if (classes.isEmpty()) {
+ return;
+ }
+ if (classes.size() == 1) {
+ callbackOnClassSelection.accept(classes.get(0));
+ return;
+ }
+ PsiClassListCellRenderer renderer = new PsiClassListCellRenderer();
+ classes.sort(renderer.getComparator());
+ // JBList has no generics in AS 2.2. TODO: Add generics here when we migrate to AS 2.3.
+ JBList list = new JBList(classes);
+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ list.setCellRenderer(renderer);
+ JBPopupFactory.getInstance()
+ .createListPopupBuilder(list)
+ .setTitle("Choose test class to run")
+ .setMovable(false)
+ .setResizable(false)
+ .setRequestFocus(true)
+ .setItemChoosenCallback(
+ () -> callbackOnClassSelection.accept((PsiClass) list.getSelectedValue()))
+ .createPopup()
+ .showInBestPositionFor(context.getDataContext());
+ }
+
+ static List<PsiClass> findTestSubclasses(PsiClass abstractClass) {
+ return ClassInheritorsSearch.search(abstractClass)
+ .findAll()
+ .stream()
+ .filter(JUnitUtil::isTestClass)
+ .collect(Collectors.toList());
+ }
+}
diff --git a/java/src/com/google/idea/blaze/java/run/producers/TestMethodSelectionUtil.java b/java/src/com/google/idea/blaze/java/run/producers/TestMethodSelectionUtil.java
index e19f9bf..3db22aa 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/TestMethodSelectionUtil.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/TestMethodSelectionUtil.java
@@ -27,8 +27,8 @@
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Helper functions for getting selected test methods. */
public class TestMethodSelectionUtil {
diff --git a/java/src/com/google/idea/blaze/java/run/producers/TestSizeAnnotationMap.java b/java/src/com/google/idea/blaze/java/run/producers/TestSizeAnnotationMap.java
index 13062b3..66cb44f 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/TestSizeAnnotationMap.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/TestSizeAnnotationMap.java
@@ -25,7 +25,7 @@
/** Maps method and class annotations to our test size enumeration. */
public class TestSizeAnnotationMap {
- private static ImmutableMap<String, TestIdeInfo.TestSize> ANNOTATION_TO_TEST_SIZE =
+ private static final ImmutableMap<String, TestIdeInfo.TestSize> ANNOTATION_TO_TEST_SIZE =
ImmutableMap.<String, TestIdeInfo.TestSize>builder()
.put("com.google.testing.testsize.SmallTest", TestIdeInfo.TestSize.SMALL)
.put("com.google.testing.testsize.MediumTest", TestIdeInfo.TestSize.MEDIUM)
diff --git a/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsMap.java b/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsMap.java
index ac53134..b58b8cc 100644
--- a/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsMap.java
+++ b/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsMap.java
@@ -17,7 +17,7 @@
import com.google.idea.blaze.base.ideinfo.TargetKey;
import java.util.List;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Map of rule -> jdeps dependencies. */
public interface JdepsMap {
diff --git a/java/src/com/google/idea/blaze/java/sync/projectstructure/Jdks.java b/java/src/com/google/idea/blaze/java/sync/projectstructure/Jdks.java
index e80c98b..704f4c4 100644
--- a/java/src/com/google/idea/blaze/java/sync/projectstructure/Jdks.java
+++ b/java/src/com/google/idea/blaze/java/sync/projectstructure/Jdks.java
@@ -36,9 +36,9 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Utility methods related to IDEA JDKs. */
public class Jdks {
diff --git a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabColorProvider.java b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabColorProvider.java
index 91234b1..b3e3b2e 100644
--- a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabColorProvider.java
+++ b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabColorProvider.java
@@ -20,8 +20,8 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.JBColor;
import java.awt.Color;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/** Changes the color for unsynced files. */
public class BlazeJavaSyncStatusEditorTabColorProvider implements EditorTabColorProvider {
diff --git a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabTitleProvider.java b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabTitleProvider.java
index aa96de8..6597752 100644
--- a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabTitleProvider.java
+++ b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabTitleProvider.java
@@ -18,7 +18,7 @@
import com.intellij.openapi.fileEditor.impl.EditorTabTitleProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Changes the tab title for unsynced files. */
public class BlazeJavaSyncStatusEditorTabTitleProvider implements EditorTabTitleProvider {
diff --git a/java/src/com/google/idea/blaze/java/ui/BlazeIntelliJProblemsView.java b/java/src/com/google/idea/blaze/java/ui/BlazeIntelliJProblemsView.java
index a2f0582..2c58b33 100644
--- a/java/src/com/google/idea/blaze/java/ui/BlazeIntelliJProblemsView.java
+++ b/java/src/com/google/idea/blaze/java/ui/BlazeIntelliJProblemsView.java
@@ -41,7 +41,7 @@
public void addMessage(IssueOutput issue, UUID sessionId) {
VirtualFile virtualFile =
issue.getFile() != null
- ? VfsUtil.findFileByIoFile(issue.getFile(), true /* refresh */)
+ ? VfsUtil.findFileByIoFile(issue.getFile(), /* refresh */ true)
: null;
CompilerMessageCategory category =
issue.getCategory() == IssueOutput.Category.ERROR
diff --git a/java/src/com/google/idea/blaze/java/wizard2/BlazeNewProjectWizard.java b/java/src/com/google/idea/blaze/java/wizard2/BlazeNewProjectWizard.java
index 62be22e..b609203 100644
--- a/java/src/com/google/idea/blaze/java/wizard2/BlazeNewProjectWizard.java
+++ b/java/src/com/google/idea/blaze/java/wizard2/BlazeNewProjectWizard.java
@@ -19,7 +19,7 @@
import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
import com.intellij.projectImport.ProjectImportProvider;
import java.awt.event.ActionListener;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
final class BlazeNewProjectWizard extends AddModuleWizard {
public BlazeNewProjectWizard(ProjectImportProvider provider) {
diff --git a/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaAbstractTestCaseConfigurationProducerTest.java b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaAbstractTestCaseConfigurationProducerTest.java
new file mode 100644
index 0000000..b30fa3e
--- /dev/null
+++ b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaAbstractTestCaseConfigurationProducerTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2017 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.java.run.producers;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TargetMapBuilder;
+import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataManager;
+import com.google.idea.blaze.base.model.primitives.TargetExpression;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.producer.BlazeRunConfigurationProducerTestCase;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.openapi.util.EmptyRunnable;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassOwner;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiMethod;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Integration tests for {@link BlazeJavaAbstractTestCaseConfigurationProducer}. */
+@RunWith(JUnit4.class)
+public class BlazeJavaAbstractTestCaseConfigurationProducerTest
+ extends BlazeRunConfigurationProducerTestCase {
+
+ @Test
+ public void testNonAbstractClassIgnored() {
+ PsiFile javaFile =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass {",
+ " @org.junit.Test",
+ " public void testMethod1() {}",
+ " @org.junit.Test",
+ " public void testMethod2() {}",
+ "}");
+
+ PsiClass javaClass = ((PsiClassOwner) javaFile).getClasses()[0];
+ assertThat(javaClass).isNotNull();
+
+ ConfigurationContext context = createContextFromPsi(javaClass);
+ ConfigurationFromContext fromContext =
+ new BlazeJavaAbstractTestCaseConfigurationProducer()
+ .createConfigurationFromContext(context);
+ assertThat(fromContext).isNull();
+ }
+
+ @Test
+ public void testConfigurationCreatedFromAbstractClass() {
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+ PsiFile abstractClassFile =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/AbstractTestCase.java"),
+ "package com.google.test;",
+ "public abstract class AbstractTestCase {}");
+
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "import com.google.test.AbstractTestCase;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass extends AbstractTestCase {",
+ " @org.junit.Test",
+ " public void testMethod1() {}",
+ " @org.junit.Test",
+ " public void testMethod2() {}",
+ "}");
+
+ PsiClass javaClass = ((PsiClassOwner) abstractClassFile).getClasses()[0];
+ assertThat(javaClass).isNotNull();
+
+ ConfigurationContext context = createContextFromPsi(abstractClassFile);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(BlazeJavaAbstractTestCaseConfigurationProducer.class))
+ .isTrue();
+ assertThat(fromContext.getSourceElement()).isEqualTo(javaClass);
+
+ RunConfiguration config = fromContext.getConfiguration();
+ assertThat(config).isInstanceOf(BlazeCommandRunConfiguration.class);
+ BlazeCommandRunConfiguration blazeConfig = (BlazeCommandRunConfiguration) config;
+ assertThat(blazeConfig.getTarget()).isNull();
+ assertThat(blazeConfig.getName()).isEqualTo("AbstractTestCase");
+
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ BlazeJavaAbstractTestCaseConfigurationProducer.chooseSubclass(
+ fromContext, context, EmptyRunnable.INSTANCE);
+
+ assertThat(blazeConfig.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:TestClass"));
+ assertThat(getTestFilterContents(blazeConfig))
+ .isEqualTo(BlazeFlags.TEST_FILTER + "=com.google.test.TestClass#");
+ }
+
+ @Test
+ public void testConfigurationCreatedFromMethodInAbstractClass() {
+ PsiFile abstractClassFile =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/AbstractTestCase.java"),
+ "package com.google.test;",
+ "public abstract class AbstractTestCase {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "import com.google.test.AbstractTestCase;",
+ "import org.junit.runner.RunWith;",
+ "import org.junit.runners.JUnit4;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass extends AbstractTestCase {}");
+
+ PsiClass javaClass = ((PsiClassOwner) abstractClassFile).getClasses()[0];
+ PsiMethod method = PsiUtils.findFirstChildOfClassRecursive(javaClass, PsiMethod.class);
+ assertThat(method).isNotNull();
+
+ ConfigurationContext context = createContextFromPsi(method);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(BlazeJavaAbstractTestCaseConfigurationProducer.class))
+ .isTrue();
+ assertThat(fromContext.getSourceElement()).isEqualTo(method);
+
+ RunConfiguration config = fromContext.getConfiguration();
+ assertThat(config).isInstanceOf(BlazeCommandRunConfiguration.class);
+ BlazeCommandRunConfiguration blazeConfig = (BlazeCommandRunConfiguration) config;
+ assertThat(blazeConfig.getTarget()).isNull();
+ assertThat(blazeConfig.getName()).isEqualTo("AbstractTestCase.testMethod");
+
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ BlazeJavaAbstractTestCaseConfigurationProducer.chooseSubclass(
+ fromContext, context, EmptyRunnable.INSTANCE);
+
+ assertThat(blazeConfig.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:TestClass"));
+ assertThat(getTestFilterContents(blazeConfig))
+ .isEqualTo(BlazeFlags.TEST_FILTER + "=com.google.test.TestClass#testMethod$");
+ }
+}
diff --git a/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassConfigurationProducerTest.java b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassConfigurationProducerTest.java
index 6135b2f..87c8f28 100644
--- a/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassConfigurationProducerTest.java
+++ b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassConfigurationProducerTest.java
@@ -17,64 +17,31 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.base.BlazeIntegrationTestCase;
-import com.google.idea.blaze.base.EditorTestHelper;
-import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.JavaIdeInfo;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
-import com.google.idea.blaze.base.ideinfo.TargetMap;
import com.google.idea.blaze.base.ideinfo.TargetMapBuilder;
import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
import com.google.idea.blaze.base.model.MockBlazeProjectDataManager;
-import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.run.BlazeRunConfiguration;
-import com.google.idea.blaze.base.sync.SyncCache;
+import com.google.idea.blaze.base.run.producer.BlazeRunConfigurationProducerTestCase;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
-import com.google.idea.blaze.base.sync.workspace.BlazeRoots;
-import com.intellij.execution.Location;
-import com.intellij.execution.PsiLocation;
-import com.intellij.execution.RunnerAndConfigurationSettings;
-import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.LangDataKeys;
-import com.intellij.openapi.module.ModuleUtil;
-import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
-import com.intellij.testFramework.MapDataContext;
-import java.io.File;
-import org.jetbrains.annotations.Nullable;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-/** Integration tests for {@link BlazeJavaMainClassConfigurationProducer}. */
+/** Integration tests for {@link BlazeJavaMainClassRunConfigurationProducer}. */
@RunWith(JUnit4.class)
-public class BlazeJavaMainClassConfigurationProducerTest extends BlazeIntegrationTestCase {
-
- private EditorTestHelper editorTest;
-
- @Before
- public final void doSetup() {
- BlazeProjectDataManager mockProjectDataManager =
- new MockBlazeProjectDataManager(getMockBlazeProjectDataBuilder().build());
- registerProjectService(BlazeProjectDataManager.class, mockProjectDataManager);
- editorTest = new EditorTestHelper(getProject(), testFixture);
- }
-
- @After
- public final void doTearDown() {
- SyncCache.getInstance(getProject()).clear();
- }
+public class BlazeJavaMainClassConfigurationProducerTest
+ extends BlazeRunConfigurationProducerTestCase {
@Test
public void testUniqueJavaBinaryChosen() {
- setTargets(
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
TargetMapBuilder.builder()
.addTarget(
TargetIdeInfo.builder()
@@ -83,14 +50,16 @@
.addSource(sourceRoot("com/google/binary/MainClass.java"))
.build())
.build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
PsiFile javaClass =
- workspace.createPsiFile(
+ createAndIndexFile(
WorkspacePath.createIfValid("com/google/binary/MainClass.java"),
"package com.google.binary;",
"import java.lang.String;",
"public class MainClass {",
- " public static void main(String[] args) {}",
+ " public static void main(java.lang.String[] args) {}",
"}");
RunConfiguration config = createConfigurationFromLocation(javaClass);
@@ -103,7 +72,8 @@
@Test
public void testNoJavaBinaryChosenIfNotInRDeps() {
- setTargets(
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
TargetMapBuilder.builder()
.addTarget(
TargetIdeInfo.builder()
@@ -112,14 +82,16 @@
.addSource(sourceRoot("com/google/binary/OtherClass.java"))
.build())
.build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
PsiFile javaClass =
- workspace.createPsiFile(
+ createAndIndexFile(
WorkspacePath.createIfValid("com/google/binary/MainClass.java"),
"package com.google.binary;",
"import java.lang.String;",
"public class MainClass {",
- " public static void main(String[] args) {}",
+ " public static void main(java.lang.String[] args) {}",
"}");
assertThat(createConfigurationFromLocation(javaClass))
@@ -128,7 +100,8 @@
@Test
public void testNoResultForClassWithoutMainMethod() {
- setTargets(
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
TargetMapBuilder.builder()
.addTarget(
TargetIdeInfo.builder()
@@ -138,9 +111,11 @@
.setJavaInfo(JavaIdeInfo.builder().setMainClass("com.google.binary.MainClass"))
.build())
.build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
PsiFile javaClass =
- workspace.createPsiFile(
+ createAndIndexFile(
WorkspacePath.createIfValid("com/google/binary/MainClass.java"),
"package com.google.binary;",
"public class MainClass {}");
@@ -150,7 +125,8 @@
@Test
public void testJavaBinaryWithMatchingNameChosen() {
- setTargets(
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
TargetMapBuilder.builder()
.addTarget(
TargetIdeInfo.builder()
@@ -165,14 +141,16 @@
.addSource(sourceRoot("com/google/binary/MainClass.java"))
.build())
.build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
PsiFile javaClass =
- workspace.createPsiFile(
+ createAndIndexFile(
WorkspacePath.createIfValid("com/google/binary/MainClass.java"),
"package com.google.binary;",
"import java.lang.String;",
"public class MainClass {",
- " public static void main(String[] args) {}",
+ " public static void main(java.lang.String[] args) {}",
"}");
RunConfiguration config = createConfigurationFromLocation(javaClass);
@@ -184,7 +162,8 @@
@Test
public void testJavaBinaryWithMatchingMainClassChosen() {
- setTargets(
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
TargetMapBuilder.builder()
.addTarget(
TargetIdeInfo.builder()
@@ -200,14 +179,16 @@
.addSource(sourceRoot("com/google/binary/MainClass.java"))
.build())
.build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
PsiFile javaClass =
- workspace.createPsiFile(
+ createAndIndexFile(
WorkspacePath.createIfValid("com/google/binary/MainClass.java"),
"package com.google.binary;",
"import java.lang.String;",
"public class MainClass {",
- " public static void main(String[] args) {}",
+ " public static void main(java.lang.String[] args) {}",
"}");
RunConfiguration config = createConfigurationFromLocation(javaClass);
@@ -217,48 +198,4 @@
assertThat(blazeConfig.getTarget())
.isEqualTo(TargetExpression.fromString("//com/google/binary:OtherName"));
}
-
- @Nullable
- private RunConfiguration createConfigurationFromLocation(PsiFile psiFile) {
- // a nauseating hack to force IntelliJ to recognize 'main' methods...
- workspace.createPsiFile(
- WorkspacePath.createIfValid("java/lang/String.java"),
- "package java.lang;",
- "public class String {}");
- editorTest.openFileInEditor(psiFile);
-
- final MapDataContext dataContext = new MapDataContext();
-
- dataContext.put(CommonDataKeys.PROJECT, getProject());
- dataContext.put(LangDataKeys.MODULE, ModuleUtil.findModuleForPsiElement(psiFile));
- dataContext.put(Location.DATA_KEY, PsiLocation.fromPsiElement(psiFile));
- RunnerAndConfigurationSettings settings =
- ConfigurationContext.getFromContext(dataContext).getConfiguration();
- return settings != null ? settings.getConfiguration() : null;
- }
-
- private MockBlazeProjectDataBuilder getMockBlazeProjectDataBuilder() {
- String executionRootPath = "usr/local/_blaze_";
- VirtualFile vf = fileSystem.createDirectory(executionRootPath);
- BlazeRoots fakeRoots =
- new BlazeRoots(
- new File(vf.getPath()),
- ImmutableList.of(workspaceRoot.directory()),
- new ExecutionRootPath("out/crosstool/bin"),
- new ExecutionRootPath("out/crosstool/gen"),
- null);
- return MockBlazeProjectDataBuilder.builder(workspaceRoot).setBlazeRoots(fakeRoots);
- }
-
- private void setTargets(TargetMap targets) {
- BlazeProjectDataManager mockProjectDataManager =
- new MockBlazeProjectDataManager(
- getMockBlazeProjectDataBuilder().setTargetMap(targets).build());
- registerProjectService(BlazeProjectDataManager.class, mockProjectDataManager);
- SyncCache.getInstance(getProject()).clear();
- }
-
- private static ArtifactLocation sourceRoot(String relativePath) {
- return ArtifactLocation.builder().setRelativePath(relativePath).setIsSource(true).build();
- }
}
diff --git a/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducerTest.java b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducerTest.java
new file mode 100644
index 0000000..ecf15d1
--- /dev/null
+++ b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducerTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2017 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.java.run.producers;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TargetMapBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataManager;
+import com.google.idea.blaze.base.model.primitives.TargetExpression;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.producer.BlazeRunConfigurationProducerTestCase;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassOwner;
+import com.intellij.psi.PsiFile;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Integration tests for {@link BlazeJavaTestClassConfigurationProducer}. */
+@RunWith(JUnit4.class)
+public class BlazeJavaTestClassConfigurationProducerTest
+ extends BlazeRunConfigurationProducerTestCase {
+
+ @Test
+ public void testProducedFromPsiFile() {
+ PsiFile javaFile =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass {",
+ " @org.junit.Test",
+ " public void testMethod1() {}",
+ " @org.junit.Test",
+ " public void testMethod2() {}",
+ "}");
+
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ ConfigurationContext context = createContextFromPsi(javaFile);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(BlazeJavaTestClassConfigurationProducer.class)).isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:TestClass"));
+ assertThat(getTestFilterContents(config)).isEqualTo("--test_filter=com.google.test.TestClass#");
+ assertThat(config.getName()).isEqualTo("Blaze test TestClass");
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+
+ @Test
+ public void testProducedFromPsiClass() {
+ PsiFile javaFile =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass {",
+ " @org.junit.Test",
+ " public void testMethod1() {}",
+ " @org.junit.Test",
+ " public void testMethod2() {}",
+ "}");
+
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ PsiClass javaClass = ((PsiClassOwner) javaFile).getClasses()[0];
+ assertThat(javaClass).isNotNull();
+
+ ConfigurationContext context = createContextFromPsi(javaClass);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(BlazeJavaTestClassConfigurationProducer.class)).isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:TestClass"));
+ assertThat(getTestFilterContents(config)).isEqualTo("--test_filter=com.google.test.TestClass#");
+ assertThat(config.getName()).isEqualTo("Blaze test TestClass");
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+}
diff --git a/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducerTest.java b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducerTest.java
new file mode 100644
index 0000000..bd8118e
--- /dev/null
+++ b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2017 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.java.run.producers;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TargetMapBuilder;
+import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataManager;
+import com.google.idea.blaze.base.model.primitives.TargetExpression;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.producer.BlazeRunConfigurationProducerTestCase;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiMethod;
+import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Integration tests for {@link BlazeJavaTestMethodConfigurationProducer}. */
+@RunWith(JUnit4.class)
+public class BlazeJavaTestMethodConfigurationProducerTest
+ extends BlazeRunConfigurationProducerTestCase {
+
+ @Test
+ public void testProducedFromPsiMethod() {
+ PsiFile javaFile =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass {",
+ " @org.junit.Test",
+ " public void testMethod1() {}",
+ "}");
+
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ PsiMethod method = PsiUtils.findFirstChildOfClassRecursive(javaFile, PsiMethod.class);
+ assertThat(method).isNotNull();
+
+ ConfigurationContext context = createContextFromPsi(method);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(BlazeJavaTestMethodConfigurationProducer.class)).isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:TestClass"));
+ assertThat(getTestFilterContents(config))
+ .isEqualTo("--test_filter=com.google.test.TestClass#testMethod1$");
+ assertThat(config.getName()).isEqualTo("Blaze test TestClass.testMethod1");
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+}
diff --git a/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/MultipleJavaClassesTestConfigurationProducerTest.java b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/MultipleJavaClassesTestConfigurationProducerTest.java
new file mode 100644
index 0000000..731743a
--- /dev/null
+++ b/java/tests/integrationtests/com/google/idea/blaze/java/run/producers/MultipleJavaClassesTestConfigurationProducerTest.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2017 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.java.run.producers;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
+import com.google.idea.blaze.base.ideinfo.TargetMapBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataBuilder;
+import com.google.idea.blaze.base.model.MockBlazeProjectDataManager;
+import com.google.idea.blaze.base.model.primitives.TargetExpression;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.producer.BlazeRunConfigurationProducerTestCase;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.actions.ConfigurationFromContext;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Integration tests for {@link MultipleJavaClassesTestConfigurationProducer}. */
+@RunWith(JUnit4.class)
+public class MultipleJavaClassesTestConfigurationProducerTest
+ extends BlazeRunConfigurationProducerTestCase {
+
+ private SourceFolder javaSourceRoot;
+
+ @Before
+ public final void addSourceFolder() {
+ // create a source root so that the package prefixes are correct.
+ VirtualFile pkgRoot = workspace.createDirectory(new WorkspacePath("java"));
+ ApplicationManager.getApplication()
+ .runWriteAction(
+ () -> {
+ final ModifiableRootModel model =
+ ModuleRootManager.getInstance(testFixture.getModule()).getModifiableModel();
+ ContentEntry contentEntry = model.getContentEntries()[0];
+ javaSourceRoot = contentEntry.addSourceFolder(pkgRoot, false, "");
+ model.commit();
+ });
+
+ BlazeProjectDataManager mockProjectDataManager =
+ new MockBlazeProjectDataManager(MockBlazeProjectDataBuilder.builder(workspaceRoot).build());
+ registerProjectService(BlazeProjectDataManager.class, mockProjectDataManager);
+ }
+
+ @After
+ public final void removeSourceFolder() {
+ ApplicationManager.getApplication()
+ .runWriteAction(
+ () -> {
+ final ModifiableRootModel model =
+ ModuleRootManager.getInstance(testFixture.getModule()).getModifiableModel();
+ ContentEntry contentEntry = model.getContentEntries()[0];
+ contentEntry.removeSourceFolder(javaSourceRoot);
+ model.commit();
+ });
+ }
+
+ @Test
+ public void testProducedFromDirectory() {
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ PsiDirectory directory =
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+
+ ConfigurationContext context = createContextFromPsi(directory);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(MultipleJavaClassesTestConfigurationProducer.class))
+ .isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:TestClass"));
+ assertThat(getTestFilterContents(config)).isEqualTo("--test_filter=com.google.test");
+ assertThat(config.getName()).isEqualTo("Blaze test all in directory 'test'");
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+
+ @Test
+ public void testProducedFromDirectoryWithNestedTests() {
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ PsiDirectory directory = workspace.createPsiDirectory(new WorkspacePath("java/com/google"));
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+
+ ConfigurationContext context = createContextFromPsi(directory);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(MultipleJavaClassesTestConfigurationProducer.class))
+ .isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:TestClass"));
+ assertThat(getTestFilterContents(config)).isEqualTo("--test_filter=com.google");
+ assertThat(config.getName()).isEqualTo("Blaze test all in directory 'google'");
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+
+ @Test
+ public void testNoFilterIfDirectoryAtPackageRoot() {
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ PsiDirectory directory = workspace.createPsiDirectory(new WorkspacePath("java"));
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+
+ ConfigurationContext context = createContextFromPsi(directory);
+ List<ConfigurationFromContext> configurations = context.getConfigurationsFromContext();
+ assertThat(configurations).hasSize(1);
+
+ ConfigurationFromContext fromContext = configurations.get(0);
+ assertThat(fromContext.isProducedBy(MultipleJavaClassesTestConfigurationProducer.class))
+ .isTrue();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(getTestFilterContents(config)).isNull();
+ assertThat(config.getName()).isEqualTo("Blaze test test:TestClass");
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+
+ @Test
+ public void testNotProducedFromDirectoryWithoutTests() {
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ PsiDirectory directory =
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+
+ ConfigurationContext context = createContextFromPsi(directory);
+ assertThat(
+ new MultipleJavaClassesTestConfigurationProducer()
+ .createConfigurationFromContext(context))
+ .isNull();
+ }
+
+ @Test
+ public void testNotProducedFromSingleTestFile() {
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass")
+ .addSource(sourceRoot("java/com/google/test/TestClass.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+ PsiFile file =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+
+ ConfigurationContext context = createContextFromPsi(file);
+ assertThat(
+ new MultipleJavaClassesTestConfigurationProducer()
+ .createConfigurationFromContext(context))
+ .isNull();
+ }
+
+ @Test
+ public void testProducedFromTestFiles() {
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:allTests")
+ .addSource(sourceRoot("java/com/google/test/TestClass1.java"))
+ .addSource(sourceRoot("java/com/google/test/TestClass2.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+ PsiFile testClass1 =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass1.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass1 {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+ PsiFile testClass2 =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass2.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass2 {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+
+ ConfigurationContext context =
+ createContextFromMultipleElements(new PsiElement[] {testClass1, testClass2});
+ ConfigurationFromContext fromContext =
+ new MultipleJavaClassesTestConfigurationProducer().createConfigurationFromContext(context);
+ assertThat(fromContext).isNotNull();
+ assertThat(fromContext.getConfiguration()).isInstanceOf(BlazeCommandRunConfiguration.class);
+
+ BlazeCommandRunConfiguration config =
+ (BlazeCommandRunConfiguration) fromContext.getConfiguration();
+ assertThat(config.getTarget())
+ .isEqualTo(TargetExpression.fromString("//java/com/google/test:allTests"));
+ assertThat(getTestFilterContents(config))
+ .isEqualTo("--test_filter=com.google.test.TestClass1#|com.google.test.TestClass2#");
+ assertThat(config.getName()).isEqualTo("Blaze test TestClass1 and 1 others");
+ assertThat(getCommandType(config)).isEqualTo(BlazeCommandName.TEST);
+ }
+
+ @Test
+ public void testNotProducedFromTestFilesInDifferentTestTargets() {
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass1")
+ .addSource(sourceRoot("java/com/google/test/TestClass1.java"))
+ .build())
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:TestClass2")
+ .addSource(sourceRoot("java/com/google/test/TestClass2.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+ PsiFile testClass1 =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass1.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass1 {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+ PsiFile testClass2 =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/TestClass2.java"),
+ "package com.google.test;",
+ "@org.junit.runner.RunWith(org.junit.runners.JUnit4.class)",
+ "public class TestClass2 {",
+ " @org.junit.Test",
+ " public void testMethod() {}",
+ "}");
+
+ ConfigurationContext context =
+ createContextFromMultipleElements(new PsiElement[] {testClass1, testClass2});
+ assertThat(
+ new MultipleJavaClassesTestConfigurationProducer()
+ .createConfigurationFromContext(context))
+ .isNull();
+ }
+
+ @Test
+ public void testNotProducedFromNonTestFiles() {
+ MockBlazeProjectDataBuilder builder = MockBlazeProjectDataBuilder.builder(workspaceRoot);
+ builder.setTargetMap(
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setKind("java_test")
+ .setLabel("//java/com/google/test:allTests")
+ .addSource(sourceRoot("java/com/google/test/NonTestClass1.java"))
+ .addSource(sourceRoot("java/com/google/test/NonTestClass2.java"))
+ .build())
+ .build());
+ registerProjectService(
+ BlazeProjectDataManager.class, new MockBlazeProjectDataManager(builder.build()));
+
+ workspace.createPsiDirectory(new WorkspacePath("java/com/google/test"));
+ PsiFile testClass1 =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/NonTestClass1.java"),
+ "package com.google.test;",
+ "public class NonTestClass1 {");
+ PsiFile testClass2 =
+ createAndIndexFile(
+ new WorkspacePath("java/com/google/test/NonTestClass2.java"),
+ "package com.google.test;",
+ "public class NonTestClass2 {}");
+
+ ConfigurationContext context =
+ createContextFromMultipleElements(new PsiElement[] {testClass1, testClass2});
+ ConfigurationFromContext fromContext =
+ new MultipleJavaClassesTestConfigurationProducer().createConfigurationFromContext(context);
+ assertThat(fromContext).isNull();
+ }
+}
diff --git a/java/tests/unittests/com/google/idea/blaze/java/run/BlazeJavaRunProfileStateTest.java b/java/tests/unittests/com/google/idea/blaze/java/run/BlazeJavaRunProfileStateTest.java
index 622105e..d31ef3f 100644
--- a/java/tests/unittests/com/google/idea/blaze/java/run/BlazeJavaRunProfileStateTest.java
+++ b/java/tests/unittests/com/google/idea/blaze/java/run/BlazeJavaRunProfileStateTest.java
@@ -16,10 +16,13 @@
package com.google.idea.blaze.java.run;
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.BlazeTestCase;
+import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.command.BuildFlagsProvider;
@@ -60,8 +63,7 @@
@Override
protected void initTest(
@NotNull Container applicationServices, @NotNull Container projectServices) {
- projectServices.register(
- BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
+ projectServices.register(BlazeImportSettingsManager.class, new BlazeImportSettingsManager());
BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
ExperimentService experimentService = new MockExperimentService();
@@ -75,6 +77,11 @@
BlazeCommandRunConfigurationHandlerProvider.EP_NAME,
BlazeCommandRunConfigurationHandlerProvider.class);
handlerProviderEp.registerExtension(new BlazeCommandGenericRunConfigurationHandlerProvider());
+ ExtensionPointImpl<BuildSystemProvider> buildSystemProviderExtensionPoint =
+ registerExtensionPoint(BuildSystemProvider.EP_NAME, BuildSystemProvider.class);
+ BuildSystemProvider buildSystemProvider = mock(BuildSystemProvider.class);
+ when(buildSystemProvider.getBinaryPath()).thenReturn("/usr/bin/blaze");
+ buildSystemProviderExtensionPoint.registerExtension(buildSystemProvider);
configuration =
new BlazeCommandRunConfigurationType().getFactory().createTemplateConfiguration(project);
@@ -93,7 +100,7 @@
configuration,
ProjectViewSet.builder().build(),
ImmutableList.of(),
- false /* debug */)
+ /* debug */ false)
.toList())
.isEqualTo(
ImmutableList.of(
@@ -102,7 +109,6 @@
BlazeFlags.getToolTagFlag(),
"--flag1",
"--flag2",
- "--test_output=streamed",
"--",
"//label:rule"));
}
@@ -119,7 +125,7 @@
configuration,
ProjectViewSet.builder().build(),
ImmutableList.of(),
- true /* debug */)
+ /* debug */ true)
.toList())
.isEqualTo(
ImmutableList.of(
@@ -143,7 +149,7 @@
configuration,
ProjectViewSet.builder().build(),
ImmutableList.of(),
- true /* debug */)
+ /* debug */ true)
.toList())
.isEqualTo(
ImmutableList.of(
diff --git a/java/tests/unittests/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporterTest.java b/java/tests/unittests/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporterTest.java
index ad731d7..7ff7620 100644
--- a/java/tests/unittests/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporterTest.java
+++ b/java/tests/unittests/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporterTest.java
@@ -16,9 +16,7 @@
package com.google.idea.blaze.java.sync.importer;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -83,8 +81,8 @@
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -94,7 +92,7 @@
public class BlazeJavaWorkspaceImporterTest extends BlazeTestCase {
private static final String FAKE_WORKSPACE_ROOT = "/root";
- private WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File(FAKE_WORKSPACE_ROOT));
+ private final WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File(FAKE_WORKSPACE_ROOT));
private static final String FAKE_GEN_ROOT_EXECUTION_PATH_FRAGMENT =
"blaze-out/gcc-4.X.Y-crosstool-v17-hybrid-grtev3-k8-fastbuild/bin";
@@ -124,7 +122,7 @@
}
private BlazeContext context;
- private ErrorCollector errorCollector = new ErrorCollector();
+ private final ErrorCollector errorCollector = new ErrorCollector();
private final JdepsMock jdepsMap = new JdepsMock();
private JavaWorkingSet workingSet = null;
private final WorkspaceLanguageSettings workspaceLanguageSettings =
@@ -139,8 +137,7 @@
BlazeExecutor blazeExecutor = new MockBlazeExecutor();
applicationServices.register(BlazeExecutor.class, blazeExecutor);
- projectServices.register(
- BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
+ projectServices.register(BlazeImportSettingsManager.class, new BlazeImportSettingsManager());
BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
// will silently fall back to FilePathJavaPackageReader
@@ -195,7 +192,7 @@
BlazeJavaImportResult result =
importWorkspace(workspaceRoot, TargetMapBuilder.builder(), ProjectView.builder().build());
errorCollector.assertNoIssues();
- assertTrue(result.contentEntries.isEmpty());
+ assertThat(result.contentEntries).isEmpty();
}
@Test
@@ -233,10 +230,10 @@
BlazeJavaImportResult result = importWorkspace(workspaceRoot, targetMapBuilder, projectView);
errorCollector.assertNoIssues();
- assertEquals(1, result.buildOutputJars.size());
+ assertThat(result.buildOutputJars).hasSize(1);
ArtifactLocation compilerOutputLib = result.buildOutputJars.iterator().next();
assertNotNull(compilerOutputLib);
- assertTrue(compilerOutputLib.relativePath.endsWith("example_debug.jar"));
+ assertThat(compilerOutputLib.relativePath).endsWith("example_debug.jar");
assertThat(result.contentEntries)
.containsExactly(
@@ -668,7 +665,7 @@
BlazeJavaImportResult result = importWorkspace(workspaceRoot, response, projectView);
errorCollector.assertNoIssues();
- assertEquals(1, result.libraries.size());
+ assertThat(result.libraries).hasSize(1);
}
@Test
@@ -713,7 +710,7 @@
BlazeJavaImportResult result = importWorkspace(workspaceRoot, response, projectView);
errorCollector.assertNoIssues();
- assertEquals(1, result.libraries.size());
+ assertThat(result.libraries).hasSize(1);
}
@Test
@@ -761,7 +758,7 @@
BlazeJavaImportResult result = importWorkspace(workspaceRoot, response, projectView);
errorCollector.assertNoIssues();
- assertEquals(1, result.libraries.size()); // The libraries were merged
+ assertThat(result.libraries).hasSize(1); // The libraries were merged
}
@Test
@@ -1394,7 +1391,7 @@
return null;
}
- private ArtifactLocation source(String relativePath) {
+ private static ArtifactLocation source(String relativePath) {
return ArtifactLocation.builder()
.setRelativePath(relativePath)
.setIsSource(true)
diff --git a/java/tests/unittests/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculatorTest.java b/java/tests/unittests/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculatorTest.java
index 25fac98..8545f55 100644
--- a/java/tests/unittests/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculatorTest.java
+++ b/java/tests/unittests/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculatorTest.java
@@ -71,12 +71,12 @@
private MockInputStreamProvider mockInputStreamProvider;
private SourceDirectoryCalculator sourceDirectoryCalculator;
- private BlazeContext context = new BlazeContext();
- private ErrorCollector issues = new ErrorCollector();
+ private final BlazeContext context = new BlazeContext();
+ private final ErrorCollector issues = new ErrorCollector();
private MockExperimentService experimentService;
- private WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File("/root"));
- private ArtifactLocationDecoder decoder =
+ private final WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File("/root"));
+ private final ArtifactLocationDecoder decoder =
(ArtifactLocationDecoder)
artifactLocation -> new File("/root", artifactLocation.getRelativePath());
@@ -894,14 +894,12 @@
.build()),
ImmutableList.of("com.google"));
ImmutableMap<TargetKey, ArtifactLocation> manifests =
- ImmutableMap.<TargetKey, ArtifactLocation>builder()
- .put(
- TargetKey.forPlainTarget(LABEL),
- ArtifactLocation.builder()
- .setRelativePath("java/com/test.manifest")
- .setIsSource(true)
- .build())
- .build();
+ ImmutableMap.of(
+ TargetKey.forPlainTarget(LABEL),
+ ArtifactLocation.builder()
+ .setRelativePath("java/com/test.manifest")
+ .setIsSource(true)
+ .build());
Map<TargetKey, Map<ArtifactLocation, String>> manifestMap =
readPackageManifestFiles(manifests, getDecoder("/root"));
@@ -921,14 +919,12 @@
ImmutableList.of("java/com/google/Bla.java"),
ImmutableList.of("com.google"));
ImmutableMap<TargetKey, ArtifactLocation> manifests =
- ImmutableMap.<TargetKey, ArtifactLocation>builder()
- .put(
- TargetKey.forPlainTarget(LABEL),
- ArtifactLocation.builder()
- .setRelativePath("java/com/test.manifest")
- .setIsSource(true)
- .build())
- .build();
+ ImmutableMap.of(
+ TargetKey.forPlainTarget(LABEL),
+ ArtifactLocation.builder()
+ .setRelativePath("java/com/test.manifest")
+ .setIsSource(true)
+ .build());
Map<TargetKey, Map<ArtifactLocation, String>> manifestMap =
readPackageManifestFiles(manifests, getDecoder("/root"));
@@ -1006,14 +1002,12 @@
"package com.google.different;\n public class Bla {}");
ImmutableMap<TargetKey, ArtifactLocation> manifests =
- ImmutableMap.<TargetKey, ArtifactLocation>builder()
- .put(
- TargetKey.forPlainTarget(LABEL),
- ArtifactLocation.builder()
- .setRelativePath("java/com/test.manifest")
- .setIsSource(true)
- .build())
- .build();
+ ImmutableMap.of(
+ TargetKey.forPlainTarget(LABEL),
+ ArtifactLocation.builder()
+ .setRelativePath("java/com/test.manifest")
+ .setIsSource(true)
+ .build());
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
@@ -1099,17 +1093,15 @@
BlazeRoots roots =
new BlazeRoots(
root,
- ImmutableList.of(root),
new ExecutionRootPath("out/crosstool/bin"),
new ExecutionRootPath("out/crosstool/gen"),
null);
- return new ArtifactLocationDecoderImpl(
- roots, new WorkspacePathResolverImpl(workspaceRoot, roots));
+ return new ArtifactLocationDecoderImpl(roots, new WorkspacePathResolverImpl(workspaceRoot));
}
private static class MockInputStreamProvider implements InputStreamProvider {
- private final Map<String, InputStream> javaFiles = new HashMap<String, InputStream>();
+ private final Map<String, InputStream> javaFiles = new HashMap<>();
public MockInputStreamProvider addFile(String filePath, String javaSrc) {
try {
diff --git a/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfiguration.java b/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfiguration.java
index 528cac4..bee62dd 100644
--- a/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfiguration.java
+++ b/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfiguration.java
@@ -343,7 +343,8 @@
protected BlazeCommand buildBlazeCommand(Project project, ProjectViewSet projectViewSet) {
BlazeCommand.Builder command =
- BlazeCommand.builder(Blaze.getBuildSystem(getProject()), BlazeCommandName.BUILD)
+ BlazeCommand.builder(
+ Blaze.getBuildSystemProvider(project).getBinaryPath(), BlazeCommandName.BUILD)
.addTargets(getTarget())
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
.addBlazeFlags(blazeFlags.getFlags())
diff --git a/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginDeployer.java b/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginDeployer.java
index c06caf2..a75ffd2 100644
--- a/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginDeployer.java
+++ b/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginDeployer.java
@@ -45,7 +45,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Handles finding files to deploy and copying these into the sandbox. */
class BlazeIntellijPluginDeployer {
diff --git a/proto_deps/BUILD b/proto/BUILD
similarity index 100%
rename from proto_deps/BUILD
rename to proto/BUILD
diff --git a/proto_deps/proto_deps.jar b/proto/proto_deps.jar
similarity index 100%
rename from proto_deps/proto_deps.jar
rename to proto/proto_deps.jar
Binary files differ
diff --git a/sdkcompat/BUILD b/sdkcompat/BUILD
index ce19ce5..a3b2a13 100644
--- a/sdkcompat/BUILD
+++ b/sdkcompat/BUILD
@@ -7,15 +7,14 @@
java_library(
name = "sdkcompat",
srcs = select_for_plugin_api({
- "android-studio-145.1617.8": glob(["v145/**"]),
- "android-studio-2.3.0.3": glob(["v162/**"]),
- "android-studio-2.3.0.4": glob(["v162/**"]),
- "intellij-2016.3.1": glob(["v163/**"]),
- "intellij-162.2032.8": glob(["v162/**"]),
- "clion-162.1967.7": glob(
- ["v162/**"],
- exclude = ["v162/com/google/idea/sdkcompat/debugger/**"],
- ),
+ "android-studio-145.1617.8": ["//sdkcompat/v145"],
+ "android-studio-2.3.0.3": ["//sdkcompat/v162"],
+ "android-studio-2.3.0.4": ["//sdkcompat/v162"],
+ "android-studio-2.3.0.6": ["//sdkcompat/v162"],
+ "intellij-2016.3.1": ["//sdkcompat/v163"],
+ "intellij-162.2032.8": ["//sdkcompat/v162"],
+ "clion-162.1967.7": ["//sdkcompat/v162"],
+ "clion-2016.3.2": ["//sdkcompat/v163"],
}),
visibility = ["//visibility:public"],
deps = [
diff --git a/sdkcompat/v145/BUILD b/sdkcompat/v145/BUILD
new file mode 100644
index 0000000..a12549d
--- /dev/null
+++ b/sdkcompat/v145/BUILD
@@ -0,0 +1,23 @@
+# Description: Indirections for SDK changes to the underlying platform library.
+
+licenses(["notice"]) # Apache 2.0
+
+load("//intellij_platform_sdk:build_defs.bzl", "select_for_ide")
+
+filegroup(
+ name = "v145",
+ srcs = glob([
+ "com/google/idea/sdkcompat/codestyle/**",
+ "com/google/idea/sdkcompat/smrunner/**",
+ "com/google/idea/sdkcompat/transactions/**",
+ "com/google/idea/sdkcompat/vcs/**",
+ ]) + select_for_ide(
+ android_studio = glob([
+ "com/google/idea/sdkcompat/debugger/**",
+ "com/google/idea/sdkcompat/cidr/**",
+ ]),
+ clion = glob(["com/google/idea/sdkcompat/cidr/**"]),
+ intellij = glob(["com/google/idea/sdkcompat/debugger/**"]),
+ ),
+ visibility = ["//sdkcompat:__pkg__"],
+)
diff --git a/sdkcompat/v145/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java b/sdkcompat/v145/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java
new file mode 100644
index 0000000..66a868e
--- /dev/null
+++ b/sdkcompat/v145/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java
@@ -0,0 +1,12 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.execution.CidrConsoleBuilder;
+
+/** Adapter to extend two bridge different SDK versions. */
+public class CidrConsoleBuilderAdapter extends CidrConsoleBuilder {
+
+ public CidrConsoleBuilderAdapter(Project project) {
+ super(project);
+ }
+}
diff --git a/sdkcompat/v145/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java b/sdkcompat/v145/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java
new file mode 100644
index 0000000..ccf31fe
--- /dev/null
+++ b/sdkcompat/v145/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java
@@ -0,0 +1,28 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.lang.workspace.OCResolveConfiguration;
+import com.jetbrains.cidr.lang.workspace.OCWorkspace;
+import com.jetbrains.cidr.lang.workspace.OCWorkspaceModificationTrackers;
+import javax.annotation.Nullable;
+
+/** Adapter to extend two bridge different SDK versions. */
+public abstract class OCWorkspaceAdapter implements OCWorkspace {
+
+ private final Project project;
+
+ protected OCWorkspaceAdapter(Project project) {
+ this.project = project;
+ }
+
+ @Nullable
+ @Override
+ public OCResolveConfiguration getSelectedResolveConfiguration() {
+ return null;
+ }
+
+ @Override
+ public OCWorkspaceModificationTrackers getModificationTrackers() {
+ return OCWorkspaceModificationTrackersCompatUtils.getTrackers(project);
+ }
+}
diff --git a/sdkcompat/v145/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java b/sdkcompat/v145/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java
new file mode 100644
index 0000000..4b17895
--- /dev/null
+++ b/sdkcompat/v145/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java
@@ -0,0 +1,25 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.lang.workspace.OCWorkspaceModificationTrackers;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Handles changes to modification trackers between our supported versions. */
+public class OCWorkspaceModificationTrackersCompatUtils {
+
+ private static final Map<Project, OCWorkspaceModificationTrackers> trackers = new HashMap<>();
+
+ public static OCWorkspaceModificationTrackers getTrackers(Project project) {
+ return trackers.computeIfAbsent(project, OCWorkspaceModificationTrackers::new);
+ }
+
+ /** Must be called inside a write action, on the EDT. */
+ public static void incrementModificationCounts(Project project) {
+ OCWorkspaceModificationTrackers modTrackers = getTrackers(project);
+ modTrackers.getProjectFilesListTracker().incModificationCount();
+ modTrackers.getSourceFilesListTracker().incModificationCount();
+ modTrackers.getBuildConfigurationChangesTracker().incModificationCount();
+ modTrackers.getBuildSettingsChangesTracker().incModificationCount();
+ }
+}
diff --git a/sdkcompat/v162/BUILD b/sdkcompat/v162/BUILD
new file mode 100644
index 0000000..f8ddfc1
--- /dev/null
+++ b/sdkcompat/v162/BUILD
@@ -0,0 +1,26 @@
+# Description: Indirections for SDK changes to the underlying platform library.
+
+licenses(["notice"]) # Apache 2.0
+
+load("//intellij_platform_sdk:build_defs.bzl", "select_for_ide")
+
+filegroup(
+ name = "v162",
+ srcs = glob([
+ "com/google/idea/sdkcompat/codestyle/**",
+ "com/google/idea/sdkcompat/smrunner/**",
+ "com/google/idea/sdkcompat/transactions/**",
+ "com/google/idea/sdkcompat/vcs/**",
+ ]) + select_for_ide(
+ android_studio = glob([
+ "com/google/idea/sdkcompat/debugger/**",
+ "com/google/idea/sdkcompat/cidr/**",
+ ]),
+ clion = glob([
+ "com/google/idea/sdkcompat/cidr/**",
+ "com/google/idea/sdkcompat/clion/**",
+ ]),
+ intellij = glob(["com/google/idea/sdkcompat/debugger/**"]),
+ ),
+ visibility = ["//sdkcompat:__pkg__"],
+)
diff --git a/sdkcompat/v162/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java b/sdkcompat/v162/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java
new file mode 100644
index 0000000..66a868e
--- /dev/null
+++ b/sdkcompat/v162/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java
@@ -0,0 +1,12 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.execution.CidrConsoleBuilder;
+
+/** Adapter to extend two bridge different SDK versions. */
+public class CidrConsoleBuilderAdapter extends CidrConsoleBuilder {
+
+ public CidrConsoleBuilderAdapter(Project project) {
+ super(project);
+ }
+}
diff --git a/sdkcompat/v162/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java b/sdkcompat/v162/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java
new file mode 100644
index 0000000..ccf31fe
--- /dev/null
+++ b/sdkcompat/v162/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java
@@ -0,0 +1,28 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.lang.workspace.OCResolveConfiguration;
+import com.jetbrains.cidr.lang.workspace.OCWorkspace;
+import com.jetbrains.cidr.lang.workspace.OCWorkspaceModificationTrackers;
+import javax.annotation.Nullable;
+
+/** Adapter to extend two bridge different SDK versions. */
+public abstract class OCWorkspaceAdapter implements OCWorkspace {
+
+ private final Project project;
+
+ protected OCWorkspaceAdapter(Project project) {
+ this.project = project;
+ }
+
+ @Nullable
+ @Override
+ public OCResolveConfiguration getSelectedResolveConfiguration() {
+ return null;
+ }
+
+ @Override
+ public OCWorkspaceModificationTrackers getModificationTrackers() {
+ return OCWorkspaceModificationTrackersCompatUtils.getTrackers(project);
+ }
+}
diff --git a/sdkcompat/v162/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java b/sdkcompat/v162/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java
new file mode 100644
index 0000000..4b17895
--- /dev/null
+++ b/sdkcompat/v162/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java
@@ -0,0 +1,25 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.lang.workspace.OCWorkspaceModificationTrackers;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Handles changes to modification trackers between our supported versions. */
+public class OCWorkspaceModificationTrackersCompatUtils {
+
+ private static final Map<Project, OCWorkspaceModificationTrackers> trackers = new HashMap<>();
+
+ public static OCWorkspaceModificationTrackers getTrackers(Project project) {
+ return trackers.computeIfAbsent(project, OCWorkspaceModificationTrackers::new);
+ }
+
+ /** Must be called inside a write action, on the EDT. */
+ public static void incrementModificationCounts(Project project) {
+ OCWorkspaceModificationTrackers modTrackers = getTrackers(project);
+ modTrackers.getProjectFilesListTracker().incModificationCount();
+ modTrackers.getSourceFilesListTracker().incModificationCount();
+ modTrackers.getBuildConfigurationChangesTracker().incModificationCount();
+ modTrackers.getBuildSettingsChangesTracker().incModificationCount();
+ }
+}
diff --git a/sdkcompat/v162/com/google/idea/sdkcompat/clion/CMakeActionList.java b/sdkcompat/v162/com/google/idea/sdkcompat/clion/CMakeActionList.java
new file mode 100644
index 0000000..9f58cf3
--- /dev/null
+++ b/sdkcompat/v162/com/google/idea/sdkcompat/clion/CMakeActionList.java
@@ -0,0 +1,22 @@
+package com.google.idea.sdkcompat.clion;
+
+import com.google.common.collect.ImmutableSet;
+import com.jetbrains.cidr.cpp.cmake.actions.ChangeCMakeProjectContentRootAction;
+import com.jetbrains.cidr.cpp.cmake.actions.DropCMakeCacheAction;
+import com.jetbrains.cidr.cpp.cmake.actions.OpenCMakeSettingsAction;
+import com.jetbrains.cidr.cpp.cmake.actions.ReloadCMakeProjectAction;
+import com.jetbrains.cidr.cpp.cmake.actions.ToggleCMakeAutoReloadAction;
+
+/** Handles CMake actions which have changed between our supported versions. */
+public class CMakeActionList {
+
+ public static ImmutableSet<String> CMAKE_ACTION_IDS =
+ ImmutableSet.of(
+ ChangeCMakeProjectContentRootAction.ID,
+ DropCMakeCacheAction.ID,
+ OpenCMakeSettingsAction.ID,
+ ReloadCMakeProjectAction.ID,
+ ToggleCMakeAutoReloadAction.ID,
+ // 'CMake' > 'Show Generated CMake Files' action
+ "CMake.ShowGeneratedDir");
+}
diff --git a/sdkcompat/v163/BUILD b/sdkcompat/v163/BUILD
new file mode 100644
index 0000000..ca51bb8
--- /dev/null
+++ b/sdkcompat/v163/BUILD
@@ -0,0 +1,26 @@
+# Description: Indirections for SDK changes to the underlying platform library.
+
+licenses(["notice"]) # Apache 2.0
+
+load("//intellij_platform_sdk:build_defs.bzl", "select_for_ide")
+
+filegroup(
+ name = "v163",
+ srcs = glob([
+ "com/google/idea/sdkcompat/codestyle/**",
+ "com/google/idea/sdkcompat/smrunner/**",
+ "com/google/idea/sdkcompat/transactions/**",
+ "com/google/idea/sdkcompat/vcs/**",
+ ]) + select_for_ide(
+ android_studio = glob([
+ "com/google/idea/sdkcompat/debugger/**",
+ "com/google/idea/sdkcompat/cidr/**",
+ ]),
+ clion = glob([
+ "com/google/idea/sdkcompat/cidr/**",
+ "com/google/idea/sdkcompat/clion/**",
+ ]),
+ intellij = glob(["com/google/idea/sdkcompat/debugger/**"]),
+ ),
+ visibility = ["//sdkcompat:__pkg__"],
+)
diff --git a/sdkcompat/v163/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java b/sdkcompat/v163/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java
new file mode 100644
index 0000000..0ed4265
--- /dev/null
+++ b/sdkcompat/v163/com/google/idea/sdkcompat/cidr/CidrConsoleBuilderAdapter.java
@@ -0,0 +1,12 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.execution.CidrConsoleBuilder;
+
+/** Adapter to extend two bridge different SDK versions. */
+public class CidrConsoleBuilderAdapter extends CidrConsoleBuilder {
+
+ public CidrConsoleBuilderAdapter(Project project) {
+ super(project, null, null);
+ }
+}
diff --git a/sdkcompat/v163/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java b/sdkcompat/v163/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java
new file mode 100644
index 0000000..1c4d586
--- /dev/null
+++ b/sdkcompat/v163/com/google/idea/sdkcompat/cidr/OCWorkspaceAdapter.java
@@ -0,0 +1,9 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.lang.workspace.OCWorkspace;
+
+/** Adapter to extend two bridge different SDK versions. */
+public abstract class OCWorkspaceAdapter implements OCWorkspace {
+ protected OCWorkspaceAdapter(Project project) {}
+}
diff --git a/sdkcompat/v163/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java b/sdkcompat/v163/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java
new file mode 100644
index 0000000..1f38a39
--- /dev/null
+++ b/sdkcompat/v163/com/google/idea/sdkcompat/cidr/OCWorkspaceModificationTrackersCompatUtils.java
@@ -0,0 +1,21 @@
+package com.google.idea.sdkcompat.cidr;
+
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.lang.workspace.OCWorkspaceModificationTrackers;
+
+/** Handles changes to modification trackers between our supported versions. */
+public class OCWorkspaceModificationTrackersCompatUtils {
+
+ public static OCWorkspaceModificationTrackers getTrackers(Project project) {
+ return OCWorkspaceModificationTrackers.getInstance(project);
+ }
+
+ /** Must be called inside a write action, on the EDT. */
+ public static void incrementModificationCounts(Project project) {
+ OCWorkspaceModificationTrackers modTrackers = getTrackers(project);
+ modTrackers.getProjectFilesListTracker().incModificationCount();
+ modTrackers.getSourceFilesListTracker().incModificationCount();
+ modTrackers.getSelectedResolveConfigurationTracker().incModificationCount();
+ modTrackers.getBuildSettingsChangesTracker().incModificationCount();
+ }
+}
diff --git a/sdkcompat/v163/com/google/idea/sdkcompat/clion/CMakeActionList.java b/sdkcompat/v163/com/google/idea/sdkcompat/clion/CMakeActionList.java
new file mode 100644
index 0000000..007bd23
--- /dev/null
+++ b/sdkcompat/v163/com/google/idea/sdkcompat/clion/CMakeActionList.java
@@ -0,0 +1,22 @@
+package com.google.idea.sdkcompat.clion;
+
+import com.google.common.collect.ImmutableSet;
+import com.jetbrains.cidr.cpp.cmake.actions.ChangeCMakeProjectContentRootAction;
+import com.jetbrains.cidr.cpp.cmake.actions.ClearCMakeCacheAndReloadAction;
+import com.jetbrains.cidr.cpp.cmake.actions.OpenCMakeSettingsAction;
+import com.jetbrains.cidr.cpp.cmake.actions.ReloadCMakeProjectAction;
+import com.jetbrains.cidr.cpp.cmake.actions.ToggleCMakeAutoReloadAction;
+
+/** Handles CMake actions which have changed between our supported versions. */
+public class CMakeActionList {
+
+ public static ImmutableSet<String> CMAKE_ACTION_IDS =
+ ImmutableSet.of(
+ ChangeCMakeProjectContentRootAction.ID,
+ ClearCMakeCacheAndReloadAction.ID,
+ OpenCMakeSettingsAction.ID,
+ ReloadCMakeProjectAction.ID,
+ ToggleCMakeAutoReloadAction.ID,
+ // 'CMake' > 'Show Generated CMake Files' action
+ "CMake.ShowGeneratedDir");
+}
diff --git a/version.bzl b/version.bzl
index 85514a2..f56966e 100644
--- a/version.bzl
+++ b/version.bzl
@@ -1,3 +1,3 @@
"""Version of the blaze plugin."""
-VERSION = "2017.01.30.4"
+VERSION = "2017.02.13.1"