Merge pull request #90 from brendandouglas/master
Import of bazel plugin using copybara
diff --git a/BUILD b/BUILD
index 99282bc..5e26650 100644
--- a/BUILD
+++ b/BUILD
@@ -4,6 +4,13 @@
licenses(["notice"]) # Apache 2.0
+# Changelog file
+filegroup(
+ name = "changelog",
+ srcs = ["CHANGELOG"],
+ visibility = ["//:__subpackages__"],
+)
+
# IJwB tests, run with an IntelliJ plugin SDK
test_suite(
name = "ijwb_tests",
@@ -16,6 +23,10 @@
"//java:integration_tests",
"//java:unit_tests",
"//plugin_dev:integration_tests",
+ "//python:integration_tests",
+ "//python:unit_tests",
+ "//scala:integration_tests",
+ "//scala:unit_tests",
],
)
@@ -38,5 +49,6 @@
tests = [
"//base:unit_tests",
"//cpp:unit_tests",
+ "//python:unit_tests",
],
)
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..32034b6
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,101 @@
+v2017.05.08
+===========
+* Add Python support to CLion
+* Fix some bazel targets not being linkified in the run configuration console
+ output
+* Add an action to open a workspace file outside your project (File > Open
+ Workspace File...)
+* Add an action to add a source directory to your bazel project (Bazel >
+ Project > Add Directory To Project...)
+* CLion: fix project directories being cleared when reopening a project
+
+v2017.04.17
+===========
+* Add support for IntelliJ 2017.1
+* Support bazel build sharding for large projects
+* Detect out-of-memory errors during sync, and suggest enabling sharding
+* Add documentation links for .bazelproject items
+
+v2017.04.03
+===========
+* Add python support for IntelliJ
+* Prefetch project files on project open, prior to initial indexing
+* Handle nested junit test classes
+
+v2017.03.15
+===========
+* Bazel: WORKSPACE file language integration (syntax highlighting, navigation,
+ etc.)
+* Bazel: Find usages, navigation support for external workspace labels
+* Expand macros in run configuration build flags
+
+v2017.02.27
+===========
+* Add CLion support
+* Run configuration support for abstract test classes/methods
+* Support running all test classes in a directory
+* BUILD support: don't suggest private symbols in 'load' statement autocomplete
+
+v2017.02.13
+===========
+* Test UI support for parameterized tests
+* Test UI support for sharded tests, run locally
+* BUILD: Fix navigation for overridden built-in symbols
+* BUILD: Add auto-complete for fully-qualified class names
+
+v2017.01.30
+============
+* Integrate bazel test results with the IDE's test runner UI.
+* Add support for sharing run configurations
+* Restructure Bazel menu items
+
+v2017.01.09
+===========
+* Create source roots for all directories matching 'test_sources'.
+* When viewing source files for supported but inactive languages, suggest
+ enabling support for that language.
+* BUILD: Add syntax highlight/autocomplete support for more built-in functions.
+* Fix java debugger connection timeout
+* Basic support for Go-lang projects
+
+v2016.12.5
+==========
+* BUILD files: add syntax hightlighting for built-in names
+* BUILD files: support aliased load statements
+* ASwB: enable NDK support
+
+v1.12
+=====
+* Add autocomplete in run configuration target editor.
+* Fix debugging of java_binary targets with args
+
+v1.11
+=====
+* Completely suppress JUnit for Bazel projects, removing a common source of
+ confusion.
+* Improve sync working set / partial sync to include more targets that
+ users might expect should be included.
+* Add more history to import wizard.
+
+v1.10
+=====
+* Compatibility with 2016.2.4
+* Improve create run configuration from scratch experience
+
+v1.9
+==========
+* Better tolerance of broken BUILD files during sync
+* Sync working set action -- sync only the files you're
+ working on.
+* BUILD file support: performance improvements.
+* Unified run configurations -- there is only one type,
+ the Bazel Command Run Configuration.
+* Add test rule chooser heuristics, to support some common
+ test genrules.
+
+v1.8
+==========
+* Add local jar cache to improve performance and robustness.
+* Support filtered gen jars to allow mixed generated/non-
+ generated rules (requires bazel release to activate).
+* Abbreviate generated run configuration names.
diff --git a/README.md b/README.md
index a6ba730..439b85e 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,8 @@
## Installation
You can find our plugin in the Jetbrains plugin repository by going to
-`Settings -> Browse Repositories`, and searching for `IntelliJ with Bazel`
-or `Android Studio with Bazel`.
+`Settings -> Browse Repositories`, and searching for `IntelliJ with Bazel`,
+`Android Studio with Bazel`, or `CLion with Bazel`.
## Usage
@@ -25,6 +25,6 @@
## Building the plugin
-Install Bazel, then run 'bazel build //ijwb:ijwb_bazel --define=ij_product=intellij-latest'
+Install Bazel, then run `bazel build //ijwb:ijwb_bazel --define=ij_product=intellij-latest`
from the project root. This will create a plugin jar in
-'bazel-genfiles/ijwb/ijwb_bazel.jar'.
+`bazel-genfiles/ijwb/ijwb_bazel.jar`.
diff --git a/WORKSPACE b/WORKSPACE
index bad62f5..9a4eaff 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -2,6 +2,14 @@
# Long-lived download links available at: https://www.jetbrains.com/intellij-repository/releases
+# The plugin api for IntelliJ 2017.1.1. This is required to build IJwB,
+# and run integration tests.
+new_http_archive(
+ name = "intellij_ce_2017_1_1",
+ build_file = "intellij_platform_sdk/BUILD.idea",
+ url = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/2017.1.1/ideaIC-2017.1.1.zip",
+)
+
# The plugin api for IntelliJ 2016.3.1. This is required to build IJwB,
# and run integration tests.
new_http_archive(
@@ -34,28 +42,62 @@
url = "https://download.jetbrains.com/cpp/CLion-2016.3.2.tar.gz",
)
-# The plugin api for Android Studio 2.3 Beta 1. This is required to build ASwB,
+# The plugin api for CLion 2017.1.1. This is required to build CLwB,
# and run integration tests.
new_http_archive(
- name = "android_studio_2_3_0_3",
- build_file = "intellij_platform_sdk/BUILD.android_studio",
- url = "https://dl.google.com/dl/android/studio/ide-zips/2.3.0.3/android-studio-ide-162.3573574-linux.zip",
+ name = "clion_2017_1_1",
+ build_file = "intellij_platform_sdk/BUILD.clion",
+ url = "https://download.jetbrains.com/cpp/CLion-2017.1.1.tar.gz",
)
-# The plugin api for Android Studio 2.3 Beta 2. This is required to build ASwB,
+# The plugin api for Android Studio 2.3.1. This is required to build ASwB,
# and run integration tests.
new_http_archive(
- name = "android_studio_2_3_0_4",
+ name = "android_studio_2_3_1_0",
build_file = "intellij_platform_sdk/BUILD.android_studio",
- url = "https://dl.google.com/dl/android/studio/ide-zips/2.3.0.4/android-studio-ide-162.3616766-linux.zip",
+ url = "https://dl.google.com/dl/android/studio/ide-zips/2.3.1.0/android-studio-ide-162.3871768-linux.zip",
)
-# The plugin api for Android Studio 2.2 stable. This is required to build ASwB,
-# and run integration tests.
+# Python plugin for IntelliJ CE 2016.3. Required at compile-time for python-specific features.
new_http_archive(
- name = "AI_145_1617_8",
- build_file = "intellij_platform_sdk/BUILD.android_studio",
- url = "https://dl.google.com/dl/android/studio/ide-zips/2.2.0.12/android-studio-ide-145.3276617-linux.zip",
+ name = "python_2016_3",
+ build_file_content = "\n".join([
+ "java_import(",
+ " name = 'python',",
+ " jars = ['python/lib/python.jar'],",
+ " visibility = ['//visibility:public'],",
+ ")"]),
+ url = "https://plugins.jetbrains.com/files/7322/32326/python-community-163.298.zip",
+)
+
+# Python plugin for IntelliJ CE 2017.1. Required at compile-time for python-specific features.
+new_http_archive(
+ name = "python_2017_1",
+ build_file_content = "\n".join([
+ "java_import(",
+ " name = 'python',",
+ " jars = ['python-ce/lib/python-ce.jar'],",
+ " visibility = ['//visibility:public'],",
+ ")"]),
+ url = "https://plugins.jetbrains.com/files/7322/33704/python-ce-2017.1.171.3780.116.zip",
+)
+
+# Scala plugin for IntelliJ CE 2017.1. Required at compile-time for scala-specific features.
+new_http_archive(
+ name = "scala_2017_1",
+ build_file_content = "\n".join([
+ "java_import(",
+ " name = 'scala-library',",
+ " jars = ['Scala/lib/scala-library.jar'],",
+ ")",
+ "",
+ "java_import(",
+ " name = 'scala',",
+ " jars = ['Scala/lib/scala-plugin.jar'],",
+ " runtime_deps = [':scala-library'],",
+ " visibility = ['//visibility:public'],",
+ ")"]),
+ url = "https://plugins.jetbrains.com/files/1347/33637/scala-intellij-bin-2017.1.15.zip",
)
# LICENSE: Common Public License 1.0
diff --git a/aswb/2.2/src/com/google/idea/blaze/android/compatibility/Compatibility.java b/aswb/2.2/src/com/google/idea/blaze/android/compatibility/Compatibility.java
deleted file mode 100644
index d65d9f2..0000000
--- a/aswb/2.2/src/com/google/idea/blaze/android/compatibility/Compatibility.java
+++ /dev/null
@@ -1,138 +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.compatibility;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.tools.idea.run.ConsolePrinter;
-import com.android.tools.idea.run.editor.AndroidDebugger;
-import com.android.tools.idea.run.editor.AndroidDebuggerState;
-import com.android.tools.idea.run.tasks.DebugConnectorTask;
-import com.android.tools.idea.run.util.LaunchStatus;
-import com.intellij.execution.Executor;
-import com.intellij.execution.configurations.ConfigurationFactory;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.Sdk;
-import java.io.File;
-import java.util.List;
-import java.util.Set;
-import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.android.sdk.AndroidSdkAdditionalData;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jps.android.model.impl.JpsAndroidModuleProperties;
-
-/** Compatibility facades for Android Studio 2.2. */
-public class Compatibility {
- private Compatibility() {}
- /**
- * Facade for {@link org.jetbrains.android.sdk.AndroidSdkUtils} and {@link
- * com.android.tools.idea.sdk.AndroidSdks#getInstance()}.
- */
- public static class AndroidSdkUtils {
- private AndroidSdkUtils() {}
-
- public static Sdk findSuitableAndroidSdk(String targetHash) {
- return org.jetbrains.android.sdk.AndroidSdkUtils.findSuitableAndroidSdk(targetHash);
- }
-
- public static List<Sdk> getAllAndroidSdks() {
- return org.jetbrains.android.sdk.AndroidSdkUtils.getAllAndroidSdks();
- }
-
- public static AndroidSdkAdditionalData getAndroidSdkAdditionalData(Sdk sdk) {
- return org.jetbrains.android.sdk.AndroidSdkUtils.getAndroidSdkAdditionalData(sdk);
- }
- }
-
- /**
- * Facade for {@link com.android.tools.idea.sdk.IdeSdks} and {@link
- * com.android.tools.idea.sdk.IdeSdks#getInstance()}.
- */
- public static class IdeSdks {
- private IdeSdks() {}
-
- public static File getAndroidSdkPath() {
- return com.android.tools.idea.sdk.IdeSdks.getAndroidSdkPath();
- }
-
- public static List<Sdk> createAndroidSdkPerAndroidTarget(File androidSdkPath) {
- return com.android.tools.idea.sdk.IdeSdks.createAndroidSdkPerAndroidTarget(androidSdkPath);
- }
- }
-
- /**
- * Facade for {@link com.android.tools.idea.run.testing.AndroidTestListener} and {@link
- * com.android.tools.idea.testartifacts.instrumented.AndroidTestListener}
- */
- public static class AndroidTestListener
- extends com.android.tools.idea.run.testing.AndroidTestListener {
- public AndroidTestListener(LaunchStatus launchStatus, ConsolePrinter consolePrinter) {
- super(launchStatus, consolePrinter);
- }
- }
-
- /**
- * Facade for {@link com.android.tools.idea.run.testing.AndroidTestConsoleProperties} and {@link
- * com.android.tools.idea.testartifacts.instrumented.AndroidTestConsoleProperties}
- */
- public static class AndroidTestConsoleProperties
- extends com.android.tools.idea.run.testing.AndroidTestConsoleProperties {
- public AndroidTestConsoleProperties(RunConfiguration runConfiguration, Executor executor) {
- super(runConfiguration, executor);
- }
- }
-
- /**
- * Facade for {@link com.android.tools.idea.run.testing.AndroidTestRunConfiguration} and {@link
- * com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration}
- */
- public static class AndroidTestRunConfiguration
- extends com.android.tools.idea.run.testing.AndroidTestRunConfiguration {
- public AndroidTestRunConfiguration(Project project, ConfigurationFactory configurationFactory) {
- super(project, configurationFactory);
- }
- }
-
- /** Facade for {@link com.android.tools.idea.run.tasks.ConnectDebuggerTask}. */
- public abstract static class ConnectDebuggerTask
- extends com.android.tools.idea.run.tasks.ConnectDebuggerTask {
- protected ConnectDebuggerTask(
- Set<String> applicationIds,
- AndroidDebugger<?> debugger,
- Project project,
- boolean monitorRemoteProcess) {
- super(applicationIds, debugger, project);
- }
- }
-
- public static <S extends AndroidDebuggerState> DebugConnectorTask getConnectDebuggerTask(
- AndroidDebugger<S> androidDebugger,
- ExecutionEnvironment env,
- @Nullable AndroidVersion version,
- Set<String> applicationIds,
- AndroidFacet facet,
- S state,
- String runConfigTypeId,
- boolean monitorRemoteProcess) {
- return androidDebugger.getConnectDebuggerTask(
- env, version, applicationIds, facet, state, runConfigTypeId);
- }
-
- public static void setFacetStateIsLibraryProject(JpsAndroidModuleProperties facetState) {
- facetState.LIBRARY_PROJECT = true;
- }
-}
diff --git a/aswb/2.2/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java b/aswb/2.2/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java
deleted file mode 100644
index 20c2c22..0000000
--- a/aswb/2.2/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java
+++ /dev/null
@@ -1,40 +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.sync.model.idea;
-
-import com.android.tools.idea.model.ClassJarProvider;
-import com.google.common.collect.ImmutableList;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import java.util.List;
-import org.jetbrains.annotations.Nullable;
-
-/** Returns no class jars. Used to disable the layout editor loading jars. */
-public class BlazeClassJarProvider extends ClassJarProvider {
- public BlazeClassJarProvider(Project project) {}
-
- @Nullable
- @Override
- public VirtualFile findModuleClassFile(String className, Module module) {
- return null;
- }
-
- @Override
- public List<VirtualFile> getModuleExternalLibraries(Module module) {
- return ImmutableList.of();
- }
-}
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/AndroidTestCleanupHelper.java
deleted file mode 100644
index 6847c67..0000000
--- a/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidTestCleanupHelper.java
+++ /dev/null
@@ -1,61 +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.intellij.codeInsight.CodeInsightSettings;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.codeStyle.CodeStyleSchemes;
-import com.intellij.psi.codeStyle.CodeStyleSettings;
-import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
-import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemeImpl;
-import com.intellij.util.xmlb.XmlSerializer;
-import org.jdom.Element;
-
-/**
- * Helper class for cleaning up after Android Studio initialization. Android Studio changes code
- * insight and style settings on initialization, so we need to revert these before tearing down the
- * integration test fixture to avoid failing because of changed settings.<br>
- * 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 static void cleanUp(Project project) {
- resetCodeInsightSettings();
- resetCodeStyleSettings(project);
- }
-
- private static void resetCodeInsightSettings() {
- // We can't just use CodeInsightSettings.getState(), because it excludes fields
- // matching the default values, and thus wouldn't change anything when loaded.
- Element codeInsightElement = new Element("state");
- XmlSerializer.serializeInto(new CodeInsightSettings(), codeInsightElement);
- CodeInsightSettings.getInstance().loadState(codeInsightElement);
- }
-
- private static void resetCodeStyleSettings(Project project) {
- CodeStyleSettingsManager settingsManager = CodeStyleSettingsManager.getInstance(project);
- if (settingsManager.USE_PER_PROJECT_SETTINGS && settingsManager.PER_PROJECT_SETTINGS != null) {
- settingsManager.PER_PROJECT_SETTINGS = new CodeStyleSettings();
- } else {
- ((CodeStyleSchemeImpl)
- CodeStyleSchemes.getInstance()
- .findPreferredScheme(settingsManager.PREFERRED_PROJECT_CODE_STYLE))
- .setCodeStyleSettings(new CodeStyleSettings());
- }
- }
-}
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/AndroidTestSetupRule.java
deleted file mode 100644
index 07fc1ac..0000000
--- a/aswb/2.2/tests/utils/integration/com/google/idea/blaze/android/AndroidTestSetupRule.java
+++ /dev/null
@@ -1,38 +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.intellij.testFramework.PlatformTestCase;
-import com.intellij.util.PlatformUtils;
-import org.junit.rules.ExternalResource;
-
-/**
- * Runs before Android Studio integration tests, to ensure the AndroidStudio platform prefix is
- * honored.
- */
-public class AndroidTestSetupRule extends ExternalResource {
-
- @Override
- protected void before() throws Throwable {
- // We require idea.platform.prefix to be defined before running tests.
- // If we don't call this before setting up the test fixture, IntelliJ ignores
- // the existing value and tries a limited set of candidate prefixes until it finds
- // 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));
- // 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/src/META-INF/aswb_beta.xml b/aswb/2.3/src/META-INF/aswb_beta.xml
deleted file mode 100644
index 8df2945..0000000
--- a/aswb/2.3/src/META-INF/aswb_beta.xml
+++ /dev/null
@@ -1,35 +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.
- -->
-<idea-plugin>
- <depends>com.google.gct.test.recorder</depends>
-
- <extensions defaultExtensionNs="com.google.idea.blaze">
- <BlazeUserSettingsContributor implementation="com.google.idea.blaze.android.settings.BlazeAndroidUserSettingsContributor$BlazeAndroidUserSettingsProvider"/>
- </extensions>
-
- <extensions defaultExtensionNs="com.android.project">
- <buildSystemService implementation="com.google.idea.blaze.android.project.BlazeBuildSystemService"/>
- <featureEnableService implementation="com.google.idea.blaze.android.project.BlazeFeatureEnableService"/>
- </extensions>
-
- <extensions defaultExtensionNs="com.android.rendering">
- <renderErrorContributor implementation="com.google.idea.blaze.android.rendering.BlazeRenderErrorContributor$BlazeProvider"/>
- </extensions>
-
- <extensions defaultExtensionNs="com.google.gct.testrecorder.run">
- <testRecorderRunConfigurationProxyProvider implementation="com.google.idea.blaze.android.run.testrecorder.TestRecorderBlazeCommandRunConfigurationProxyProvider" />
- </extensions>
-</idea-plugin>
diff --git a/aswb/2.3/src/com/google/idea/blaze/android/compatibility/Compatibility.java b/aswb/2.3/src/com/google/idea/blaze/android/compatibility/Compatibility.java
deleted file mode 100644
index e614959..0000000
--- a/aswb/2.3/src/com/google/idea/blaze/android/compatibility/Compatibility.java
+++ /dev/null
@@ -1,141 +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.compatibility;
-
-import com.android.sdklib.AndroidVersion;
-import com.android.tools.idea.run.ConsolePrinter;
-import com.android.tools.idea.run.editor.AndroidDebugger;
-import com.android.tools.idea.run.editor.AndroidDebuggerState;
-import com.android.tools.idea.run.tasks.DebugConnectorTask;
-import com.android.tools.idea.run.util.LaunchStatus;
-import com.intellij.execution.Executor;
-import com.intellij.execution.configurations.ConfigurationFactory;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.Sdk;
-import java.io.File;
-import java.util.List;
-import java.util.Set;
-import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.android.sdk.AndroidSdkAdditionalData;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jps.android.model.impl.JpsAndroidModuleProperties;
-
-/** Compatibility facades for Android Studio 2.3. */
-public class Compatibility {
- private Compatibility() {}
-
- /**
- * Facade for {@link org.jetbrains.android.sdk.AndroidSdkUtils} and {@link
- * com.android.tools.idea.sdk.AndroidSdks#getInstance()}.
- */
- public static class AndroidSdkUtils {
- private AndroidSdkUtils() {}
-
- public static Sdk findSuitableAndroidSdk(String targetHash) {
- return com.android.tools.idea.sdk.AndroidSdks.getInstance()
- .findSuitableAndroidSdk(targetHash);
- }
-
- public static List<Sdk> getAllAndroidSdks() {
- return com.android.tools.idea.sdk.AndroidSdks.getInstance().getAllAndroidSdks();
- }
-
- public static AndroidSdkAdditionalData getAndroidSdkAdditionalData(Sdk sdk) {
- return com.android.tools.idea.sdk.AndroidSdks.getInstance().getAndroidSdkAdditionalData(sdk);
- }
- }
-
- /**
- * Facade for {@link com.android.tools.idea.sdk.IdeSdks} and {@link
- * com.android.tools.idea.sdk.IdeSdks#getInstance()}.
- */
- public static class IdeSdks {
- private IdeSdks() {}
-
- public static File getAndroidSdkPath() {
- return com.android.tools.idea.sdk.IdeSdks.getInstance().getAndroidSdkPath();
- }
-
- public static List<Sdk> createAndroidSdkPerAndroidTarget(File androidSdkPath) {
- return com.android.tools.idea.sdk.IdeSdks.getInstance()
- .createAndroidSdkPerAndroidTarget(androidSdkPath);
- }
- }
-
- /**
- * Facade for {@link com.android.tools.idea.run.testing.AndroidTestListener} and {@link
- * com.android.tools.idea.testartifacts.instrumented.AndroidTestListener}
- */
- public static class AndroidTestListener
- extends com.android.tools.idea.testartifacts.instrumented.AndroidTestListener {
- public AndroidTestListener(LaunchStatus launchStatus, ConsolePrinter consolePrinter) {
- super(launchStatus, consolePrinter);
- }
- }
-
- /**
- * Facade for {@link com.android.tools.idea.run.testing.AndroidTestConsoleProperties} and {@link
- * com.android.tools.idea.testartifacts.instrumented.AndroidTestConsoleProperties}
- */
- public static class AndroidTestConsoleProperties
- extends com.android.tools.idea.testartifacts.instrumented.AndroidTestConsoleProperties {
- public AndroidTestConsoleProperties(RunConfiguration runConfiguration, Executor executor) {
- super(runConfiguration, executor);
- }
- }
-
- /**
- * Facade for {@link com.android.tools.idea.run.testing.AndroidTestRunConfiguration} and {@link
- * com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration}
- */
- public static class AndroidTestRunConfiguration
- extends com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration {
- public AndroidTestRunConfiguration(Project project, ConfigurationFactory configurationFactory) {
- super(project, configurationFactory);
- }
- }
-
- /** Facade for {@link com.android.tools.idea.run.tasks.ConnectDebuggerTask}. */
- public abstract static class ConnectDebuggerTask
- extends com.android.tools.idea.run.tasks.ConnectDebuggerTask {
- protected ConnectDebuggerTask(
- Set<String> applicationIds,
- AndroidDebugger<?> debugger,
- Project project,
- boolean monitorRemoteProcess) {
- super(applicationIds, debugger, project, monitorRemoteProcess);
- }
- }
-
- public static <S extends AndroidDebuggerState> DebugConnectorTask getConnectDebuggerTask(
- AndroidDebugger<S> androidDebugger,
- ExecutionEnvironment env,
- @Nullable AndroidVersion version,
- Set<String> applicationIds,
- AndroidFacet facet,
- S state,
- String runConfigTypeId,
- boolean monitorRemoteProcess) {
- return androidDebugger.getConnectDebuggerTask(
- env, version, applicationIds, facet, state, runConfigTypeId, monitorRemoteProcess);
- }
-
- public static void setFacetStateIsLibraryProject(JpsAndroidModuleProperties facetState) {
- facetState.PROJECT_TYPE = com.android.builder.model.AndroidProject.PROJECT_TYPE_LIBRARY;
- }
-}
diff --git a/aswb/BUILD b/aswb/BUILD
index 16fc99b..7772ebc 100644
--- a/aswb/BUILD
+++ b/aswb/BUILD
@@ -11,7 +11,6 @@
"stamped_plugin_xml",
)
load("//:version.bzl", "VERSION")
-load("//intellij_platform_sdk:build_defs.bzl", "select_for_plugin_api")
merged_plugin_xml(
name = "merged_plugin_xml_common",
@@ -20,14 +19,6 @@
"//base:plugin_xml",
"//cpp:plugin_xml",
"//java:plugin_xml",
- ] + select_for_plugin_api({
- # TODO(chaorenl): remove when 2.2 is obsolete
- "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"],
- }),
- visibility = [
- "//visibility:public",
],
)
@@ -41,6 +32,7 @@
stamped_plugin_xml(
name = "stamped_plugin_xml",
+ changelog_file = "//:changelog",
include_product_code_in_stamp = True,
plugin_id = "com.google.idea.bazel.aswb",
plugin_name = "Android Studio with Bazel",
@@ -51,41 +43,26 @@
java_library(
name = "aswb_lib",
- srcs = glob(["src/**/*.java"]) + select_for_plugin_api({
- # TODO(chaorenl): remove when 2.2 is obsolete
- "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"]),
- }),
+ srcs = glob(["src/**/*.java"]),
resources = glob(["resources/**/*"]),
- visibility = [
- "//visibility:public",
+ runtime_deps = [
+ "//cpp",
],
deps = [
"//base",
"//common/experiments",
- "//cpp",
"//intellij_platform_sdk:plugin_api",
"//java",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
],
)
-# TODO(chaorenl): remove when 2.2 is obsolete
java_library(
name = "integration_test_utils",
testonly = 1,
- srcs = select_for_plugin_api({
- "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"]),
- }),
+ srcs = glob(["tests/utils/integration/**/*.java"]),
deps = [
- "//base",
- "//base:integration_test_utils",
- "//base:unit_test_utils",
- "//intellij_platform_sdk:plugin_api_for_tests",
"@jsr305_annotations//jar",
"@junit//jar",
],
@@ -99,12 +76,7 @@
intellij_unit_test_suite(
name = "unit_tests",
- srcs = glob(["tests/unittests/**/*.java"]) + select_for_plugin_api({
- # TODO(chaorenl): remove when 2.2 is obsolete
- "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"]),
- }),
+ srcs = glob(["tests/unittests/**/*.java"]),
test_package_root = "com.google.idea.blaze.android",
deps = [
":aswb_lib",
@@ -114,7 +86,7 @@
"//common/experiments:unit_test_utils",
"//intellij_platform_sdk:plugin_api_for_tests",
"//java",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
"@junit//jar",
],
@@ -122,12 +94,7 @@
intellij_integration_test_suite(
name = "integration_tests",
- srcs = glob(["tests/integrationtests/**/*.java"]) + select_for_plugin_api({
- # TODO(chaorenl): remove when 2.2 is obsolete
- "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"]),
- }),
+ srcs = glob(["tests/integrationtests/**/*.java"]),
platform_prefix = "AndroidStudio",
required_plugins = "com.google.idea.bazel.aswb",
test_package_root = "com.google.idea.blaze.android",
@@ -142,9 +109,10 @@
"//base:unit_test_utils",
"//common/experiments",
"//common/experiments:unit_test_utils",
+ "//cpp",
"//intellij_platform_sdk:plugin_api_for_tests",
"//java",
- "//proto_deps",
+ "//proto:proto_deps",
"@jsr305_annotations//jar",
"@junit//jar",
],
diff --git a/aswb/aswb.bazelproject b/aswb/aswb.bazelproject
index c2f7d36..5700471 100644
--- a/aswb/aswb.bazelproject
+++ b/aswb/aswb.bazelproject
@@ -3,9 +3,6 @@
-ijwb
-plugin_dev
-clwb
- -cpp/src/com/google/idea/blaze/cpp/versioned/v162
- # TODO(chaorenl): remove when 2.2 is obsolete.
- -aswb/2.3
targets:
//aswb:aswb_bazel
diff --git a/aswb/src/META-INF/aswb.xml b/aswb/src/META-INF/aswb.xml
index d59d935..4bf7584 100644
--- a/aswb/src/META-INF/aswb.xml
+++ b/aswb/src/META-INF/aswb.xml
@@ -18,8 +18,7 @@
<depends>com.intellij.modules.androidstudio</depends>
<depends>org.jetbrains.android</depends>
- <!-- TODO(chaorenl): remove when 2.2 is obsolete -->
- <depends optional="true">com.android.tools.idea.updater</depends>
+ <depends>com.google.gct.test.recorder</depends>
<extensions defaultExtensionNs="com.intellij">
<java.elementFinder implementation="com.google.idea.blaze.android.resources.AndroidResourceClassFinder"
@@ -40,6 +39,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">
@@ -57,12 +59,13 @@
<SyncListener implementation="com.google.idea.blaze.android.cppimpl.BlazeNdkSupportEnabler"/>
<SyncListener implementation="com.google.idea.blaze.android.manifest.ManifestParser$ClearManifestParser"/>
<RunConfigurationFactory implementation="com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationFactory"/>
- <java.JavaSyncAugmenter implementation="com.google.idea.blaze.android.sync.BlazeAndroidJavaSyncAugmenter"/>
+ <JavaSyncAugmenter implementation="com.google.idea.blaze.android.sync.BlazeAndroidJavaSyncAugmenter"/>
<PrefetchFileSource implementation="com.google.idea.blaze.android.sync.AndroidPrefetchFileSource"/>
<BlazeCommandRunConfigurationHandlerProvider implementation="com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryRunConfigurationHandlerProvider"/>
<BlazeCommandRunConfigurationHandlerProvider implementation="com.google.idea.blaze.android.run.test.BlazeAndroidTestRunConfigurationHandlerProvider"/>
<BuildSystemAndroidJdkProvider implementation="com.google.idea.blaze.android.sync.BazelAndroidJdkProvider"/>
<BlazeTestEventsHandler implementation="com.google.idea.blaze.android.run.test.smrunner.BlazeAndroidTestEventsHandler"/>
+ <ProjectViewDefaultValueProvider implementation="com.google.idea.blaze.android.projectview.AndroidSdkPlatformSection$AndroidSdkPlatformProjectViewDefaultValueProvider"/>
</extensions>
<extensions defaultExtensionNs="com.android.ide">
@@ -84,6 +87,23 @@
</extensions>
<!-- END NDK SUPPORT -->
+ <extensions defaultExtensionNs="com.google.idea.blaze">
+ <BlazeUserSettingsContributor implementation="com.google.idea.blaze.android.settings.BlazeAndroidUserSettingsContributor$BlazeAndroidUserSettingsProvider"/>
+ </extensions>
+
+ <extensions defaultExtensionNs="com.android.project">
+ <buildSystemService implementation="com.google.idea.blaze.android.project.BlazeBuildSystemService"/>
+ <featureEnableService implementation="com.google.idea.blaze.android.project.BlazeFeatureEnableService"/>
+ </extensions>
+
+ <extensions defaultExtensionNs="com.android.rendering">
+ <renderErrorContributor implementation="com.google.idea.blaze.android.rendering.BlazeRenderErrorContributor$BlazeProvider"/>
+ </extensions>
+
+ <extensions defaultExtensionNs="com.google.gct.testrecorder.run">
+ <testRecorderRunConfigurationProxyProvider implementation="com.google.idea.blaze.android.run.testrecorder.TestRecorderBlazeCommandRunConfigurationProxyProvider" />
+ </extensions>
+
<application-components>
<component>
<implementation-class>com.google.idea.blaze.android.plugin.PluginCompatibilityEnforcer</implementation-class>
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/2.3/src/com/google/idea/blaze/android/project/BlazeBuildSystemService.java b/aswb/src/com/google/idea/blaze/android/project/BlazeBuildSystemService.java
similarity index 100%
rename from aswb/2.3/src/com/google/idea/blaze/android/project/BlazeBuildSystemService.java
rename to aswb/src/com/google/idea/blaze/android/project/BlazeBuildSystemService.java
diff --git a/aswb/2.3/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java b/aswb/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java
similarity index 73%
rename from aswb/2.3/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java
rename to aswb/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java
index e59f375..a43374f 100644
--- a/aswb/2.3/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java
+++ b/aswb/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java
@@ -16,7 +16,9 @@
package com.google.idea.blaze.android.project;
import com.android.tools.idea.project.FeatureEnableService;
+import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.android.settings.BlazeAndroidUserSettings;
+import com.google.idea.blaze.base.logging.EventLogger;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.common.experiments.BoolExperiment;
@@ -24,6 +26,8 @@
/** Enable features supported by the blaze integration. */
public class BlazeFeatureEnableService extends FeatureEnableService {
+ private static final EventLogger logger = EventLogger.getInstance();
+
private static final BoolExperiment ENABLE_LAYOUT_EDITOR =
new BoolExperiment("enable.layout.editor", true);
@@ -34,10 +38,13 @@
@Override
public boolean isLayoutEditorEnabled(Project project) {
- return isLayoutEditorExperimentEnabled()
- && BlazeAndroidUserSettings.getInstance().getUseLayoutEditor()
- // Can't render if we don't have the data ready.
- && BlazeProjectDataManager.getInstance(project).getBlazeProjectData() != null;
+ boolean isEnabled =
+ isLayoutEditorExperimentEnabled()
+ && BlazeAndroidUserSettings.getInstance().getUseLayoutEditor();
+ boolean isReady = BlazeProjectDataManager.getInstance(project).getBlazeProjectData() != null;
+ logger.log(
+ getClass(), "layout_editor", ImmutableMap.of("enabled", Boolean.toString(isEnabled)));
+ return isEnabled && isReady;
}
public static boolean isLayoutEditorExperimentEnabled() {
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..917da87 100644
--- a/aswb/src/com/google/idea/blaze/android/projectview/AndroidSdkPlatformSection.java
+++ b/aswb/src/com/google/idea/blaze/android/projectview/AndroidSdkPlatformSection.java
@@ -18,17 +18,20 @@
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.ProjectViewSet;
import com.google.idea.blaze.base.projectview.parser.ParseContext;
import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
+import com.google.idea.blaze.base.projectview.section.ProjectViewDefaultValueProvider;
import com.google.idea.blaze.base.projectview.section.ScalarSection;
import com.google.idea.blaze.base.projectview.section.ScalarSectionParser;
import com.google.idea.blaze.base.projectview.section.SectionKey;
import com.google.idea.blaze.base.projectview.section.SectionParser;
import com.google.idea.blaze.base.projectview.section.sections.TextBlock;
import com.google.idea.blaze.base.projectview.section.sections.TextBlockSection;
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.text.StringUtil;
import java.util.List;
@@ -60,15 +63,19 @@
public ItemType getItemType() {
return ItemType.Other;
}
+ }
+ static class AndroidSdkPlatformProjectViewDefaultValueProvider
+ implements ProjectViewDefaultValueProvider {
@Override
- public ProjectView addProjectViewDefaultValue(ProjectView projectView) {
- if (!projectView.getSectionsOfType(KEY).isEmpty()) {
- return projectView;
+ public ProjectView addProjectViewDefaultValue(
+ BuildSystem buildSystem, ProjectViewSet projectViewSet, ProjectView topLevelProjectView) {
+ if (!topLevelProjectView.getSectionsOfType(KEY).isEmpty()) {
+ return topLevelProjectView;
}
- List<Sdk> sdks = AndroidSdkUtils.getAllAndroidSdks();
+ List<Sdk> sdks = BlazeSdkProvider.getInstance().getAllAndroidSdks();
ProjectView.Builder builder =
- ProjectView.builder(projectView).add(TextBlockSection.of(TextBlock.newLine()));
+ ProjectView.builder(topLevelProjectView).add(TextBlockSection.of(TextBlock.newLine()));
if (sdks.isEmpty()) {
builder
@@ -81,7 +88,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(
@@ -95,5 +102,10 @@
}
return builder.build();
}
+
+ @Override
+ public SectionKey<?, ?> getSectionKey() {
+ return KEY;
+ }
}
}
diff --git a/aswb/2.3/src/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributor.java b/aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributor.java
similarity index 100%
rename from aswb/2.3/src/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributor.java
rename to aswb/src/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributor.java
diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java
index 6926023..eaff918 100644
--- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java
+++ b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java
@@ -18,7 +18,6 @@
import static com.google.idea.blaze.android.cppapi.NdkSupport.NDK_SUPPORT;
import com.android.tools.idea.run.ValidationError;
-import com.android.tools.idea.run.editor.AndroidDebugger;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.idea.blaze.android.cppapi.NdkSupport;
@@ -76,12 +75,8 @@
return debuggerManager;
}
- public List<String> getUserFlags() {
- return userFlags.getFlags();
- }
-
- public void setUserFlags(List<String> userFlags) {
- this.userFlags.setFlags(userFlags);
+ public RunConfigurationFlagsState getBlazeFlagsState() {
+ return userFlags;
}
public boolean isNativeDebuggingEnabled() {
@@ -92,10 +87,11 @@
this.nativeDebuggingEnabled = nativeDebuggingEnabled;
}
- public ImmutableList<String> getBuildFlags(Project project, ProjectViewSet projectViewSet) {
+ public ImmutableList<String> getExpandedBuildFlags(
+ Project project, ProjectViewSet projectViewSet) {
return ImmutableList.<String>builder()
.addAll(BlazeFlags.buildFlags(project, projectViewSet))
- .addAll(getUserFlags())
+ .addAll(getBlazeFlagsState().getExpandedFlags())
.addAll(getNativeDebuggerFlags())
.build();
}
@@ -127,19 +123,11 @@
Element deployTargetStatesElement = element.getChild(DEPLOY_TARGET_STATES_TAG);
if (deployTargetStatesElement != null) {
deployTargetManager.readExternal(deployTargetStatesElement);
- } else {
- // TODO Introduced in 1.12, remove in 1.14.
- // This was for migrating the state to a child element.
- deployTargetManager.readExternal(element);
}
Element debuggerStatesElement = element.getChild(DEBUGGER_STATES_TAG);
if (debuggerStatesElement != null) {
debuggerManager.readExternal(debuggerStatesElement);
- } else {
- // TODO Introduced in 1.12, remove in 1.14.
- // This was for migrating the state to a child element.
- debuggerManager.readExternal(element);
}
}
@@ -148,8 +136,6 @@
userFlags.writeExternal(element);
element.setAttribute(NATIVE_DEBUG_ATTR, Boolean.toString(nativeDebuggingEnabled));
- removeOldManagerState(element);
-
element.removeChildren(DEPLOY_TARGET_STATES_TAG);
Element deployTargetStatesElement = new Element(DEPLOY_TARGET_STATES_TAG);
deployTargetManager.writeExternal(deployTargetStatesElement);
@@ -161,19 +147,6 @@
element.addContent(debuggerStatesElement);
}
- // TODO Introduced in 1.12, remove in 1.14. This was for migrating state
- // and cleaning up mass amounts of duplicate state caused by never removing these elements before.
- private void removeOldManagerState(Element element) {
- // This is safe because we know only BlazeAndroidRunConfigurationDeployTargetManager
- // directly wrote option elements (via DefaultJDOMExternalizer.writeExternal) to our root.
- element.removeChildren("option");
- // BlazeAndroidRunConfigurationDebuggerManager, meanwhile, nested its state in
- // child elements named after the AndroidDebugger extension IDs.
- for (AndroidDebugger<?> debugger : AndroidDebugger.EP_NAME.getExtensions()) {
- element.removeChildren(debugger.getId());
- }
- }
-
@Override
public RunConfigurationStateEditor getEditor(Project project) {
return new BlazeAndroidRunConfigurationCommonStateEditor(this, project);
diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java
index 5351213..cb6b23c 100644
--- a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java
+++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryNormalBuildRunContext.java
@@ -33,7 +33,6 @@
import com.android.tools.idea.run.util.ProcessHandlerLaunchStatus;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
-import com.google.idea.blaze.android.compatibility.Compatibility;
import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo;
import com.google.idea.blaze.android.run.deployinfo.BlazeApkProvider;
import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector;
@@ -175,8 +174,7 @@
Set<String> packageIds,
boolean monitorRemoteProcess)
throws ExecutionException {
- return Compatibility.getConnectDebuggerTask(
- androidDebugger,
+ return androidDebugger.getConnectDebuggerTask(
env,
null,
packageIds,
diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandler.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandler.java
index 3b222f7..f57d51f 100644
--- a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandler.java
+++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationHandler.java
@@ -104,7 +104,8 @@
ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
BlazeAndroidRunConfigurationValidationUtil.validateExecution(module, facet, projectViewSet);
- ImmutableList<String> buildFlags = configState.getBuildFlags(project, projectViewSet);
+ ImmutableList<String> buildFlags =
+ configState.getCommonState().getExpandedBuildFlags(project, projectViewSet);
BlazeAndroidRunContext runContext = createRunContext(project, facet, environment, buildFlags);
return new BlazeAndroidRunConfigurationRunner(
diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationState.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationState.java
index cb368d4..8bc2076 100644
--- a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationState.java
+++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationState.java
@@ -18,10 +18,8 @@
import com.android.tools.idea.run.ValidationError;
import com.android.tools.idea.run.util.LaunchUtils;
import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState;
-import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.state.RunConfigurationState;
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.intellij.openapi.project.Project;
@@ -123,10 +121,6 @@
this.mode = mode;
}
- public ImmutableList<String> getBuildFlags(Project project, ProjectViewSet projectViewSet) {
- return commonState.getBuildFlags(project, projectViewSet);
- }
-
/**
* We collect errors rather than throwing to avoid missing fatal errors by exiting early for a
* warning.
diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java
index 2ea7ebc..da33631 100644
--- a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java
+++ b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeAndroidBinaryMobileInstallRunContext.java
@@ -30,7 +30,6 @@
import com.android.tools.idea.run.util.ProcessHandlerLaunchStatus;
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
-import com.google.idea.blaze.android.compatibility.Compatibility;
import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationIdProvider;
import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryApplicationLaunchTaskProvider;
import com.google.idea.blaze.android.run.binary.BlazeAndroidBinaryConsoleProvider;
@@ -167,8 +166,7 @@
Set<String> packageIds,
boolean monitorRemoteProcess)
throws ExecutionException {
- return Compatibility.getConnectDebuggerTask(
- androidDebugger,
+ return androidDebugger.getConnectDebuggerTask(
env,
null,
packageIds,
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..582afea 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,22 +23,18 @@
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.sync.model.AndroidSdkPlatform;
-import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData;
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.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.filecache.FileCaches;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
-import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
@@ -46,17 +42,15 @@
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.scope.output.StatusOutput;
import com.google.idea.blaze.base.settings.Blaze;
-import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.base.util.SaveUtil;
import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.projectRoots.Sdk;
import java.io.File;
-import java.nio.file.Paths;
import java.util.concurrent.CancellationException;
import javax.annotation.Nullable;
+import org.jetbrains.android.sdk.AndroidSdkUtils;
/** Builds and installs the APK using mobile-install. */
public class BlazeApkBuildStepMobileInstall implements BlazeApkBuildStep {
@@ -99,11 +93,12 @@
}
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()) {
- File adb = getSdkAdb(project);
+ File adb = AndroidSdkUtils.getAdb(project);
if (adb != null) {
command.addBlazeFlags(ImmutableList.of("--adb", adb.toString()));
}
@@ -117,13 +112,14 @@
}
WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
+ BlazeApkDeployInfoProtoHelper deployInfoHelper =
+ new BlazeApkDeployInfoProtoHelper(project, buildFlags);
+ BuildResultHelper buildResultHelper = deployInfoHelper.getBuildResultHelper();
+
command
.addTargets(label)
.addBlazeFlags(buildFlags)
- .addBlazeFlags(BlazeFlags.EXPERIMENTAL_SHOW_ARTIFACTS);
-
- BlazeApkDeployInfoProtoHelper deployInfoHelper =
- new BlazeApkDeployInfoProtoHelper(project, buildFlags);
+ .addBlazeFlags(buildResultHelper.getBuildFlags());
SaveUtil.saveAllFiles();
int retVal =
@@ -131,8 +127,7 @@
.addBlazeCommand(command.build())
.context(context)
.stderr(
- LineProcessingOutputStream.of(
- deployInfoHelper.getLineProcessor(),
+ buildResultHelper.stderr(
new IssueOutputLineProcessor(project, context, workspaceRoot)))
.build()
.run();
@@ -172,35 +167,6 @@
return deployInfoFuture;
}
- private static File getSdkAdb(Project project) {
- BlazeProjectData projectData =
- BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
- if (projectData == null) {
- return null;
- }
- BlazeAndroidSyncData syncData = projectData.syncState.get(BlazeAndroidSyncData.class);
- if (syncData == null) {
- return null;
- }
- AndroidSdkPlatform androidSdkPlatform = syncData.androidSdkPlatform;
- if (androidSdkPlatform == null) {
- return null;
- }
- Sdk sdk = AndroidSdkUtils.findSuitableAndroidSdk(androidSdkPlatform.androidSdk);
- if (sdk == null) {
- return null;
- }
- String homePath = sdk.getHomePath();
- if (homePath == null) {
- return null;
- }
- File adb = Paths.get(homePath, "platform-tools", "adb").toFile();
- if (!adb.exists()) {
- return null;
- }
- return adb;
- }
-
@Nullable
private static IDevice resolveDevice(BlazeContext context, DeviceFutures deviceFutures) {
if (deviceFutures.get().size() != 1) {
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..98e2e87 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
@@ -17,12 +17,11 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.android.manifest.ManifestParser;
-import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
-import com.google.idea.blaze.base.command.ExperimentalShowArtifactsLineProcessor;
+import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.command.info.BlazeInfo;
+import com.google.idea.blaze.base.command.info.BlazeInfoRunner;
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;
@@ -44,24 +43,23 @@
private final Project project;
private final WorkspaceRoot workspaceRoot;
private final ImmutableList<String> buildFlags;
- private final List<File> deployInfoFiles = Lists.newArrayList();
- private final LineProcessingOutputStream.LineProcessor lineProcessor =
- new ExperimentalShowArtifactsLineProcessor(
- deployInfoFiles, fileName -> fileName.endsWith(".deployinfo.pb"));
+ private final BuildResultHelper buildResultHelper;
public BlazeApkDeployInfoProtoHelper(Project project, ImmutableList<String> buildFlags) {
this.project = project;
this.buildFlags = buildFlags;
this.workspaceRoot = WorkspaceRoot.fromProject(project);
+ this.buildResultHelper =
+ BuildResultHelper.forFiles(fileName -> fileName.endsWith(".deployinfo.pb"));
}
- public LineProcessingOutputStream.LineProcessor getLineProcessor() {
- return lineProcessor;
+ public BuildResultHelper getBuildResultHelper() {
+ return buildResultHelper;
}
@Nullable
public BlazeAndroidDeployInfo readDeployInfo(BlazeContext context) {
- File deployInfoFile = Iterables.getOnlyElement(deployInfoFiles, null);
+ File deployInfoFile = Iterables.getOnlyElement(buildResultHelper.getBuildArtifacts(), null);
if (deployInfoFile == null) {
return null;
}
@@ -88,10 +86,10 @@
@Nullable
private String getExecutionRoot(BlazeContext context) {
ListenableFuture<String> execRootFuture =
- BlazeInfo.getInstance()
+ BlazeInfoRunner.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..58daf4f 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
@@ -23,10 +23,9 @@
import com.google.idea.blaze.android.run.deployinfo.BlazeApkDeployInfoProtoHelper;
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.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
-import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.filecache.FileCaches;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.model.primitives.Label;
@@ -63,17 +62,19 @@
@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);
+ BlazeApkDeployInfoProtoHelper deployInfoHelper =
+ new BlazeApkDeployInfoProtoHelper(project, buildFlags);
+ BuildResultHelper buildResultHelper = deployInfoHelper.getBuildResultHelper();
+
command
.addTargets(label)
.addBlazeFlags("--output_groups=+android_deploy_info")
.addBlazeFlags(buildFlags)
- .addBlazeFlags(BlazeFlags.EXPERIMENTAL_SHOW_ARTIFACTS);
-
- BlazeApkDeployInfoProtoHelper deployInfoHelper =
- new BlazeApkDeployInfoProtoHelper(project, buildFlags);
+ .addBlazeFlags(buildResultHelper.getBuildFlags());
SaveUtil.saveAllFiles();
int retVal =
@@ -81,8 +82,7 @@
.addBlazeCommand(command.build())
.context(context)
.stderr(
- LineProcessingOutputStream.of(
- deployInfoHelper.getLineProcessor(),
+ buildResultHelper.stderr(
new IssueOutputLineProcessor(project, context, workspaceRoot)))
.build()
.run();
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/AndroidTestConsoleProvider.java b/aswb/src/com/google/idea/blaze/android/run/test/AndroidTestConsoleProvider.java
index c0cbb24..92311c4 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/AndroidTestConsoleProvider.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/AndroidTestConsoleProvider.java
@@ -16,7 +16,7 @@
package com.google.idea.blaze.android.run.test;
import com.android.tools.idea.run.ConsoleProvider;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestConsoleProperties;
+import com.android.tools.idea.testartifacts.instrumented.AndroidTestConsoleProperties;
import com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler;
import com.google.idea.blaze.base.run.smrunner.SmRunnerUtils;
import com.intellij.execution.ExecutionException;
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..b898e42 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
@@ -15,8 +15,8 @@
*/
package com.google.idea.blaze.android.run.test;
+import com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration;
import com.google.common.base.Strings;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestRunConfiguration;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
@@ -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/BlazeAndroidTestFilter.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestFilter.java
index e5f2b1d..9002f30 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestFilter.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestFilter.java
@@ -15,8 +15,8 @@
*/
package com.google.idea.blaze.android.run.test;
+import com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration;
import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestRunConfiguration;
import com.google.idea.blaze.base.command.BlazeFlags;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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..db2cca6 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
@@ -15,8 +15,8 @@
*/
package com.google.idea.blaze.android.run.test;
+import com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration;
import com.google.common.base.Strings;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestRunConfiguration;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
@@ -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/BlazeAndroidTestRunConfigurationHandler.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java
index d63ea0c..4b94b3c 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationHandler.java
@@ -102,7 +102,8 @@
ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
BlazeAndroidRunConfigurationValidationUtil.validateExecution(module, facet, projectViewSet);
- ImmutableList<String> buildFlags = configState.getBuildFlags(project, projectViewSet);
+ ImmutableList<String> buildFlags =
+ configState.getCommonState().getExpandedBuildFlags(project, projectViewSet);
BlazeAndroidRunContext runContext = createRunContext(project, facet, environment, buildFlags);
return new BlazeAndroidRunConfigurationRunner(
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationState.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationState.java
index 62fcbb3..074b17b 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationState.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationState.java
@@ -17,10 +17,8 @@
import com.android.tools.idea.run.ValidationError;
import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState;
-import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.state.RunConfigurationState;
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.intellij.openapi.project.Project;
@@ -132,10 +130,6 @@
this.extraOptions = extraOptions;
}
- public ImmutableList<String> getBuildFlags(Project project, ProjectViewSet projectViewSet) {
- return commonState.getBuildFlags(project, projectViewSet);
- }
-
/**
* We collect errors rather than throwing to avoid missing fatal errors by exiting early for a
* warning.
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationStateEditor.java b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationStateEditor.java
index 5df4512..5e5e6c8 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationStateEditor.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/BlazeAndroidTestRunConfigurationStateEditor.java
@@ -16,10 +16,10 @@
package com.google.idea.blaze.android.run.test;
-import static com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestRunConfiguration.TEST_ALL_IN_MODULE;
-import static com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestRunConfiguration.TEST_ALL_IN_PACKAGE;
-import static com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestRunConfiguration.TEST_CLASS;
-import static com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestRunConfiguration.TEST_METHOD;
+import static com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration.TEST_ALL_IN_MODULE;
+import static com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration.TEST_ALL_IN_PACKAGE;
+import static com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration.TEST_CLASS;
+import static com.android.tools.idea.testartifacts.instrumented.AndroidTestRunConfiguration.TEST_METHOD;
import com.google.idea.blaze.base.run.state.RunConfigurationState;
import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
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..9962acf 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
@@ -33,7 +33,6 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
-import com.google.idea.blaze.android.compatibility.Compatibility;
import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo;
import com.google.idea.blaze.android.run.deployinfo.BlazeApkProvider;
import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector;
@@ -45,7 +44,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 +59,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 +92,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);
@@ -230,8 +225,7 @@
return new ConnectBlazeTestDebuggerTask(
env.getProject(), androidDebugger, packageIds, applicationIdProvider, this);
}
- return Compatibility.getConnectDebuggerTask(
- androidDebugger,
+ return androidDebugger.getConnectDebuggerTask(
env,
null,
packageIds,
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java b/aswb/src/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java
index 8e2328e..8cdeedf 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/ConnectBlazeTestDebuggerTask.java
@@ -28,9 +28,9 @@
import com.android.tools.idea.run.LaunchInfo;
import com.android.tools.idea.run.ProcessHandlerConsolePrinter;
import com.android.tools.idea.run.editor.AndroidDebugger;
+import com.android.tools.idea.run.tasks.ConnectDebuggerTask;
import com.android.tools.idea.run.tasks.ConnectJavaDebuggerTask;
import com.android.tools.idea.run.util.ProcessHandlerLaunchStatus;
-import com.google.idea.blaze.android.compatibility.Compatibility.ConnectDebuggerTask;
import com.intellij.debugger.engine.RemoteDebugProcessHandler;
import com.intellij.debugger.ui.DebuggerPanelsManager;
import com.intellij.execution.ExecutionException;
diff --git a/aswb/src/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java b/aswb/src/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java
index 2430f3c..a10773e 100644
--- a/aswb/src/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java
+++ b/aswb/src/com/google/idea/blaze/android/run/test/StockAndroidTestLaunchTask.java
@@ -22,8 +22,8 @@
import com.android.tools.idea.run.ConsolePrinter;
import com.android.tools.idea.run.tasks.LaunchTask;
import com.android.tools.idea.run.util.LaunchStatus;
+import com.android.tools.idea.testartifacts.instrumented.AndroidTestListener;
import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.android.compatibility.Compatibility.AndroidTestListener;
import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -158,6 +158,7 @@
}
@Override
+ @SuppressWarnings("FutureReturnValueIgnored")
public boolean perform(
IDevice device, final LaunchStatus launchStatus, final ConsolePrinter printer) {
printer.stdout("Running tests\n");
@@ -165,6 +166,8 @@
final RemoteAndroidTestRunner runner =
new RemoteAndroidTestRunner(testApplicationId, instrumentationTestRunner, device);
switch (configState.getTestingType()) {
+ case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_MODULE:
+ break;
case BlazeAndroidTestRunConfigurationState.TEST_ALL_IN_PACKAGE:
runner.setTestPackageName(configState.getPackageName());
break;
@@ -183,15 +186,12 @@
// run in a separate thread as this will block until the tests complete
ApplicationManager.getApplication()
.executeOnPooledThread(
- new Runnable() {
- @Override
- public void run() {
- try {
- runner.run(new AndroidTestListener(launchStatus, printer));
- } catch (Exception e) {
- LOG.info(e);
- printer.stderr("Error: Unexpected exception while running tests: " + e);
- }
+ () -> {
+ try {
+ runner.run(new AndroidTestListener(launchStatus, printer));
+ } catch (Exception e) {
+ LOG.info(e);
+ printer.stderr("Error: Unexpected exception while running tests: " + e);
}
});
diff --git a/aswb/2.3/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfiguration.java b/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfiguration.java
similarity index 100%
rename from aswb/2.3/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfiguration.java
rename to aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfiguration.java
diff --git a/aswb/2.3/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxy.java b/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxy.java
similarity index 100%
rename from aswb/2.3/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxy.java
rename to aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxy.java
diff --git a/aswb/2.3/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxyProvider.java b/aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxyProvider.java
similarity index 100%
rename from aswb/2.3/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxyProvider.java
rename to aswb/src/com/google/idea/blaze/android/run/testrecorder/TestRecorderBlazeCommandRunConfigurationProxyProvider.java
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..1d1a43b
--- /dev/null
+++ b/aswb/src/com/google/idea/blaze/android/sdk/BlazeSdkProviderImpl.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.android.sdk;
+
+import com.android.tools.idea.sdk.AndroidSdks;
+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 AndroidSdks.getInstance().getAllAndroidSdks();
+ }
+
+ @Override
+ public Sdk findSdk(String targetHash) {
+ return AndroidSdks.getInstance().findSuitableAndroidSdk(targetHash);
+ }
+
+ @Override
+ @Nullable
+ public String getSdkTargetHash(Sdk sdk) {
+ AndroidSdkAdditionalData additionalData =
+ AndroidSdks.getInstance().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/2.3/src/com/google/idea/blaze/android/settings/BlazeAndroidUserSettingsContributor.java b/aswb/src/com/google/idea/blaze/android/settings/BlazeAndroidUserSettingsContributor.java
similarity index 100%
rename from aswb/2.3/src/com/google/idea/blaze/android/settings/BlazeAndroidUserSettingsContributor.java
rename to aswb/src/com/google/idea/blaze/android/settings/BlazeAndroidUserSettingsContributor.java
diff --git a/aswb/src/com/google/idea/blaze/android/sync/AndroidPrefetchFileSource.java b/aswb/src/com/google/idea/blaze/android/sync/AndroidPrefetchFileSource.java
index 162f693..821f098 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/AndroidPrefetchFileSource.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/AndroidPrefetchFileSource.java
@@ -19,6 +19,7 @@
import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.prefetch.PrefetchFileSource;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.openapi.project.Project;
import java.io.File;
@@ -29,7 +30,10 @@
public class AndroidPrefetchFileSource implements PrefetchFileSource {
@Override
public void addFilesToPrefetch(
- Project project, BlazeProjectData blazeProjectData, Collection<File> files) {
+ Project project,
+ ProjectViewSet projectViewSet,
+ BlazeProjectData blazeProjectData,
+ Collection<File> files) {
BlazeAndroidSyncData syncData = blazeProjectData.syncState.get(BlazeAndroidSyncData.class);
if (syncData == null) {
return;
diff --git a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidJavaSyncAugmenter.java b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidJavaSyncAugmenter.java
index 084aec6..16afc3f 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidJavaSyncAugmenter.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidJavaSyncAugmenter.java
@@ -48,7 +48,7 @@
}
LibraryArtifact idlJar = androidIdeInfo.idlJar;
if (idlJar != null) {
- genJars.add(new BlazeJarLibrary(idlJar, target.key));
+ genJars.add(new BlazeJarLibrary(idlJar));
}
Set<String> whitelistedGenResourcePaths =
projectViewSet
@@ -66,7 +66,7 @@
if (!discardResourceJar) {
LibraryArtifact resourceJar = androidIdeInfo.resourceJar;
if (resourceJar != null) {
- jars.add(new BlazeJarLibrary(resourceJar, target.key));
+ jars.add(new BlazeJarLibrary(resourceJar));
}
}
}
diff --git a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidLibrarySource.java b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidLibrarySource.java
index bfff837..73bb993 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidLibrarySource.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidLibrarySource.java
@@ -19,13 +19,8 @@
import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData;
import com.google.idea.blaze.base.model.BlazeLibrary;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.projectview.section.Glob;
-import com.google.idea.blaze.base.projectview.section.Glob.GlobSet;
import com.google.idea.blaze.base.sync.libraries.LibrarySource;
-import com.google.idea.blaze.java.sync.LibraryGlobFilter;
import java.util.Collection;
-import java.util.function.Predicate;
-import javax.annotation.Nullable;
class BlazeAndroidLibrarySource extends LibrarySource.Adapter {
private final BlazeProjectData blazeProjectData;
@@ -46,12 +41,4 @@
}
return libraries.build();
}
-
- @Nullable
- @Override
- public Predicate<BlazeLibrary> getLibraryFilter() {
- // This is supplied via the SDK
- GlobSet globSet = new GlobSet(ImmutableList.of(new Glob("*/android_blaze.jar")));
- return new LibraryGlobFilter(globSet);
- }
}
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..f21d144 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java
@@ -15,20 +15,21 @@
*/
package com.google.idea.blaze.android.sync;
+import com.android.tools.idea.sdk.IdeSdks;
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;
import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData;
import com.google.idea.blaze.android.sync.projectstructure.BlazeAndroidProjectStructureSyncer;
import com.google.idea.blaze.android.sync.sdk.AndroidSdkFromProjectView;
+import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.ideinfo.TargetMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.BlazeVersionData;
@@ -49,7 +50,6 @@
import com.google.idea.blaze.base.sync.libraries.LibrarySource;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
-import com.google.idea.blaze.base.sync.workspace.BlazeRoots;
import com.google.idea.blaze.base.sync.workspace.WorkingSet;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.google.idea.blaze.java.projectview.JavaLanguageLevelSection;
@@ -111,13 +111,17 @@
@Override
public void installSdks(BlazeContext context) {
- File path = IdeSdks.getAndroidSdkPath();
+ if (ApplicationManager.getApplication().isUnitTestMode()) {
+ return;
+ }
+
+ File path = IdeSdks.getInstance().getAndroidSdkPath();
if (path != null) {
context.output(new StatusOutput("Installing SDK platforms..."));
ApplicationManager.getApplication()
.invokeAndWait(
() -> {
- IdeSdks.createAndroidSdkPerAndroidTarget(path);
+ IdeSdks.getInstance().createAndroidSdkPerAndroidTarget(path);
},
ModalityState.defaultModalityState());
}
@@ -130,7 +134,7 @@
WorkspaceRoot workspaceRoot,
ProjectViewSet projectViewSet,
WorkspaceLanguageSettings workspaceLanguageSettings,
- BlazeRoots blazeRoots,
+ BlazeInfo blazeInfo,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
ArtifactLocationDecoder artifactLocationDecoder,
@@ -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))
@@ -260,6 +264,7 @@
@Override
public boolean validateProjectView(
+ @Nullable Project project,
BlazeContext context,
ProjectViewSet projectViewSet,
WorkspaceLanguageSettings workspaceLanguageSettings) {
@@ -306,7 +311,8 @@
@Nullable
@Override
- public LibrarySource getLibrarySource(BlazeProjectData blazeProjectData) {
+ public LibrarySource getLibrarySource(
+ ProjectViewSet projectViewSet, BlazeProjectData blazeProjectData) {
if (!isAndroidWorkspace(blazeProjectData.workspaceLanguageSettings)) {
return null;
}
diff --git a/aswb/src/com/google/idea/blaze/android/sync/model/AndroidResourceModule.java b/aswb/src/com/google/idea/blaze/android/sync/model/AndroidResourceModule.java
index 73d76f5..8a2cca5 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/model/AndroidResourceModule.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/model/AndroidResourceModule.java
@@ -145,7 +145,7 @@
}
public Builder addTransitiveResourceDependency(String dependency) {
- return addTransitiveResourceDependency(new Label(dependency));
+ return addTransitiveResourceDependency(Label.create(dependency));
}
@NotNull
diff --git a/aswb/2.3/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java
similarity index 100%
rename from aswb/2.3/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java
rename to aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java
diff --git a/aswb/src/com/google/idea/blaze/android/sync/projectstructure/AndroidFacetModuleCustomizer.java b/aswb/src/com/google/idea/blaze/android/sync/projectstructure/AndroidFacetModuleCustomizer.java
index 541be52..7f04fe2 100755
--- a/aswb/src/com/google/idea/blaze/android/sync/projectstructure/AndroidFacetModuleCustomizer.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/projectstructure/AndroidFacetModuleCustomizer.java
@@ -16,7 +16,6 @@
package com.google.idea.blaze.android.sync.projectstructure;
import com.android.builder.model.AndroidProject;
-import com.google.idea.blaze.android.compatibility.Compatibility;
import com.intellij.facet.FacetManager;
import com.intellij.facet.ModifiableFacetModel;
import com.intellij.openapi.module.Module;
@@ -56,7 +55,7 @@
private static void configureFacet(AndroidFacet facet) {
JpsAndroidModuleProperties facetState = facet.getProperties();
facetState.ALLOW_USER_CONFIGURATION = false;
- Compatibility.setFacetStateIsLibraryProject(facetState);
+ facetState.PROJECT_TYPE = AndroidProject.PROJECT_TYPE_LIBRARY;
facetState.MANIFEST_FILE_RELATIVE_PATH = "";
facetState.RES_FOLDER_RELATIVE_PATH = "";
facetState.ASSETS_FOLDER_RELATIVE_PATH = "";
diff --git a/aswb/src/com/google/idea/blaze/android/sync/projectstructure/BlazeAndroidProjectStructureSyncer.java b/aswb/src/com/google/idea/blaze/android/sync/projectstructure/BlazeAndroidProjectStructureSyncer.java
index 66b020f..29a20a6 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/projectstructure/BlazeAndroidProjectStructureSyncer.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/projectstructure/BlazeAndroidProjectStructureSyncer.java
@@ -49,12 +49,13 @@
import com.google.idea.blaze.base.sync.BlazeSyncPlugin;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.base.sync.projectstructure.ModuleEditorProvider;
+import com.google.idea.blaze.base.sync.projectstructure.ModuleFinder;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.execution.RunManager;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
@@ -69,6 +70,8 @@
/** Updates the IDE's project structure. */
public class BlazeAndroidProjectStructureSyncer {
+ private static final Logger logger = Logger.getInstance(BlazeAndroidProjectStructureSyncer.class);
+
public static void updateProjectStructure(
Project project,
BlazeContext context,
@@ -214,7 +217,7 @@
public static Module ensureRunConfigurationModule(Project project, Label label) {
TargetKey targetKey = TargetKey.forPlainTarget(label);
String moduleName = moduleNameForAndroidModule(targetKey);
- Module module = ModuleManager.getInstance(project).findModuleByName(moduleName);
+ Module module = ModuleFinder.getInstance(project).findModuleByName(moduleName);
if (module != null) {
return module;
}
@@ -308,12 +311,16 @@
project, workspaceRoot, workspaceModule, androidSdkPlatform);
ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
- ModuleManager moduleManager = ModuleManager.getInstance(project);
+ ModuleFinder moduleFinder = ModuleFinder.getInstance(project);
for (AndroidResourceModule androidResourceModule :
syncData.importResult.androidResourceModules) {
TargetIdeInfo target = blazeProjectData.targetMap.get(androidResourceModule.targetKey);
String moduleName = moduleNameForAndroidModule(target.key);
- Module module = moduleManager.findModuleByName(moduleName);
+ Module module = moduleFinder.findModuleByName(moduleName);
+ if (module == null) {
+ logger.warn("No module found for resource target: " + target.key);
+ continue;
+ }
registry.put(module, androidResourceModule);
AndroidIdeInfo androidIdeInfo = target.androidIdeInfo;
@@ -345,7 +352,11 @@
project, projectViewSet, blazeProjectData, androidResourceModules);
for (TargetIdeInfo target : runConfigurationTargets) {
String moduleName = moduleNameForAndroidModule(target.key);
- Module module = moduleManager.findModuleByName(moduleName);
+ Module module = moduleFinder.findModuleByName(moduleName);
+ if (module == null) {
+ logger.warn("No module found for run configuration target: " + target.key);
+ continue;
+ }
AndroidIdeInfo androidIdeInfo = target.androidIdeInfo;
assert androidIdeInfo != null;
updateModuleFacetInMemoryState(
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
deleted file mode 100644
index 7eca0c6..0000000
--- a/aswb/tests/integrationtests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateMigrationTest.java
+++ /dev/null
@@ -1,131 +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.run;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.idea.blaze.android.BlazeAndroidIntegrationTestCase;
-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.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Tests for migrating the storage of deploy target state and debugger state in {@link
- * BlazeAndroidRunConfigurationCommonState} TODO Introduced in 1.12, remove in 1.14 when the
- * migration code in BlazeAndroidRunConfigurationCommonState is removed.
- */
-@RunWith(JUnit4.class)
-public class BlazeAndroidRunConfigurationCommonStateMigrationTest
- extends BlazeAndroidIntegrationTestCase {
-
- private static final String DEPLOY_TARGET_STATES_RAW_XML =
- "<android-deploy-target-states>"
- + " <option name=\"USE_LAST_SELECTED_DEVICE\" value=\"true\" />"
- + " <option name=\"PREFERRED_AVD\" value=\"some avd\" />"
- + "</android-deploy-target-states>";
- private static final String DEBUGGER_STATE_AUTO_RAW_XML =
- "<Auto>"
- + " <option name=\"USE_JAVA_AWARE_DEBUGGER\" value=\"true\" />"
- + " <option name=\"WORKING_DIR\" value=\"/some/directory\" />"
- + " <option name=\"TARGET_LOGGING_CHANNELS\" value=\"some channels\" />"
- + "</Auto>";
- private static final String DEBUGGER_STATE_NATIVE_RAW_XML =
- "<Native>"
- + " <option name=\"USE_JAVA_AWARE_DEBUGGER\" value=\"false\" />"
- + " <option name=\"WORKING_DIR\" value=\"\" />"
- + " <option name=\"TARGET_LOGGING_CHANNELS\""
- + " value=\"lldb process:gdb-remote packets\" />"
- + "</Native>";
- private static final String DEBUGGER_STATE_JAVA_RAW_XML = "<Java />";
- private static final String DEBUGGER_STATE_HYBRID_RAW_XML =
- "<Hybrid>"
- + " <option name=\"USE_JAVA_AWARE_DEBUGGER\" value=\"true\" />"
- + " <option name=\"WORKING_DIR\" value=\"\" />"
- + " <option name=\"TARGET_LOGGING_CHANNELS\""
- + " value=\"lldb process:gdb-remote packets\" />"
- + "</Hybrid>";
- private static final String DEBUGGER_STATE_BLAZE_AUTO_RAW_XML =
- "<BlazeAuto>"
- + " <option name=\"USE_JAVA_AWARE_DEBUGGER\" value=\"false\" />"
- + " <option name=\"WORKING_DIR\" value=\"/some/other/directory\" />"
- + " <option name=\"TARGET_LOGGING_CHANNELS\" value=\"some other channels\" />"
- + "</BlazeAuto>";
-
- private BlazeAndroidRunConfigurationCommonState state;
- private SAXBuilder saxBuilder;
- private XMLOutputter xmlOutputter;
-
- @Before
- public final void doSetup() throws Exception {
- state = new BlazeAndroidRunConfigurationCommonState(buildSystem().getName(), false);
- saxBuilder = new SAXBuilder();
- xmlOutputter = new XMLOutputter(Format.getCompactFormat());
- }
-
- private String formatRawXml(String rawXml) throws Exception {
- Element element =
- saxBuilder.build(new StringReader("<?xml version=\"1.0\"?>" + rawXml)).getRootElement();
- return xmlOutputter.outputString(element);
- }
-
- @Test
- public void readAndWriteShouldRemoveExtraElements() throws Exception {
- String oldXml =
- "<?xml version=\"1.0\"?>"
- + "<configuration blaze-native-debug=\"true\">"
- + " <blaze-user-flag>--flag1</blaze-user-flag>"
- + " <blaze-user-flag>--flag2</blaze-user-flag>"
- + " <option name=\"USE_LAST_SELECTED_DEVICE\" value=\"true\" />"
- + " <option name=\"PREFERRED_AVD\" value=\"some avd\" />"
- + DEBUGGER_STATE_AUTO_RAW_XML
- + DEBUGGER_STATE_NATIVE_RAW_XML
- + DEBUGGER_STATE_JAVA_RAW_XML
- + DEBUGGER_STATE_HYBRID_RAW_XML
- + DEBUGGER_STATE_BLAZE_AUTO_RAW_XML
- + " <option name=\"USE_LAST_SELECTED_DEVICE\" value=\"true\" />"
- + " <option name=\"PREFERRED_AVD\" value=\"some avd\" />"
- + DEBUGGER_STATE_AUTO_RAW_XML
- + DEBUGGER_STATE_NATIVE_RAW_XML
- + DEBUGGER_STATE_JAVA_RAW_XML
- + DEBUGGER_STATE_HYBRID_RAW_XML
- + DEBUGGER_STATE_BLAZE_AUTO_RAW_XML
- + "</configuration>";
- Element oldElement = saxBuilder.build(new StringReader(oldXml)).getRootElement();
-
- state.readExternal(oldElement);
- Element migratedElement = new Element("configuration");
- state.writeExternal(migratedElement);
-
- assertThat(migratedElement.getChildren()).hasSize(4);
- List<Element> flagElements = migratedElement.getChildren("blaze-user-flag");
- assertThat(flagElements).hasSize(2);
-
- Element deployTargetStatesElement = migratedElement.getChild("android-deploy-target-states");
- assertThat(xmlOutputter.outputString(deployTargetStatesElement))
- .isEqualTo(formatRawXml(DEPLOY_TARGET_STATES_RAW_XML));
-
- Element debuggerStatesElement = migratedElement.getChild("android-debugger-states");
- assertThat(debuggerStatesElement.getChildren()).hasSize(5);
- }
-}
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..0d9cba6 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,9 @@
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.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;
@@ -29,14 +30,18 @@
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
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
@@ -52,7 +57,7 @@
@Test
public void readAndWriteShouldMatch() throws InvalidDataException, WriteExternalException {
- state.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
+ state.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
state.setNativeDebuggingEnabled(true);
Element element = new Element("test");
@@ -61,7 +66,9 @@
new BlazeAndroidRunConfigurationCommonState(buildSystem().getName(), false);
readState.readExternal(element);
- assertThat(readState.getUserFlags()).containsExactly("--flag1", "--flag2").inOrder();
+ assertThat(readState.getBlazeFlagsState().getRawFlags())
+ .containsExactly("--flag1", "--flag2")
+ .inOrder();
assertThat(readState.isNativeDebuggingEnabled()).isTrue();
}
@@ -73,13 +80,16 @@
new BlazeAndroidRunConfigurationCommonState(buildSystem().getName(), false);
readState.readExternal(element);
- assertThat(readState.getUserFlags()).isEqualTo(state.getUserFlags());
+ assertThat(readState.getBlazeFlagsState().getRawFlags())
+ .isEqualTo(state.getBlazeFlagsState().getRawFlags());
assertThat(readState.isNativeDebuggingEnabled()).isEqualTo(state.isNativeDebuggingEnabled());
}
@Test
public void readShouldOmitEmptyFlags() throws InvalidDataException, WriteExternalException {
- state.setUserFlags(ImmutableList.of("hi ", "", "I'm", " ", "\t", "Josh\r\n", "\n"));
+ state
+ .getBlazeFlagsState()
+ .setRawFlags(ImmutableList.of("hi ", "", "I'm", " ", "\t", "Josh\r\n", "\n"));
Element element = new Element("test");
state.writeExternal(element);
@@ -87,14 +97,16 @@
new BlazeAndroidRunConfigurationCommonState(buildSystem().getName(), false);
readState.readExternal(element);
- assertThat(readState.getUserFlags()).containsExactly("hi", "I'm", "Josh").inOrder();
+ assertThat(readState.getBlazeFlagsState().getRawFlags())
+ .containsExactly("hi", "I'm", "Josh")
+ .inOrder();
}
@Test
public void repeatedWriteShouldNotChangeElement() throws WriteExternalException {
final XMLOutputter xmlOutputter = new XMLOutputter(Format.getCompactFormat());
- state.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
+ state.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
state.setNativeDebuggingEnabled(true);
Element firstWrite = new Element("test");
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..e72c5de 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,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.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;
@@ -32,14 +33,18 @@
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
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
@@ -56,7 +61,7 @@
@Test
public void readAndWriteShouldMatch() throws InvalidDataException, WriteExternalException {
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
- commonState.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
+ commonState.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
commonState.setNativeDebuggingEnabled(true);
state.setActivityClass("com.example.TestActivity");
@@ -74,7 +79,9 @@
readState.readExternal(element);
BlazeAndroidRunConfigurationCommonState readCommonState = readState.getCommonState();
- assertThat(readCommonState.getUserFlags()).containsExactly("--flag1", "--flag2").inOrder();
+ assertThat(readCommonState.getBlazeFlagsState().getRawFlags())
+ .containsExactly("--flag1", "--flag2")
+ .inOrder();
assertThat(readCommonState.isNativeDebuggingEnabled()).isTrue();
assertThat(readState.getActivityClass()).isEqualTo("com.example.TestActivity");
@@ -97,7 +104,8 @@
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
BlazeAndroidRunConfigurationCommonState readCommonState = readState.getCommonState();
- assertThat(readCommonState.getUserFlags()).isEqualTo(commonState.getUserFlags());
+ assertThat(readCommonState.getBlazeFlagsState().getRawFlags())
+ .isEqualTo(commonState.getBlazeFlagsState().getRawFlags());
assertThat(readCommonState.isNativeDebuggingEnabled())
.isEqualTo(commonState.isNativeDebuggingEnabled());
@@ -115,7 +123,7 @@
final XMLOutputter xmlOutputter = new XMLOutputter(Format.getCompactFormat());
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
- commonState.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
+ commonState.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
commonState.setNativeDebuggingEnabled(true);
state.setActivityClass("com.example.TestActivity");
@@ -140,7 +148,7 @@
RunConfigurationStateEditor editor = state.getEditor(getProject());
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
- commonState.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
+ commonState.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
commonState.setNativeDebuggingEnabled(true);
state.setActivityClass("com.example.TestActivity");
@@ -158,7 +166,8 @@
editor.applyEditorTo(readState);
BlazeAndroidRunConfigurationCommonState readCommonState = readState.getCommonState();
- assertThat(readCommonState.getUserFlags()).isEqualTo(commonState.getUserFlags());
+ assertThat(readCommonState.getBlazeFlagsState().getRawFlags())
+ .isEqualTo(commonState.getBlazeFlagsState().getRawFlags());
assertThat(readCommonState.isNativeDebuggingEnabled())
.isEqualTo(commonState.isNativeDebuggingEnabled());
@@ -183,7 +192,8 @@
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
BlazeAndroidRunConfigurationCommonState readCommonState = readState.getCommonState();
- assertThat(readCommonState.getUserFlags()).isEqualTo(commonState.getUserFlags());
+ assertThat(readCommonState.getBlazeFlagsState().getRawFlags())
+ .isEqualTo(commonState.getBlazeFlagsState().getRawFlags());
assertThat(readCommonState.isNativeDebuggingEnabled())
.isEqualTo(commonState.isNativeDebuggingEnabled());
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..4944264 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,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.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,14 +32,18 @@
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
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
@@ -55,7 +60,7 @@
@Test
public void readAndWriteShouldMatch() throws InvalidDataException, WriteExternalException {
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
- commonState.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
+ commonState.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
commonState.setNativeDebuggingEnabled(true);
state.setTestingType(BlazeAndroidTestRunConfigurationState.TEST_METHOD);
@@ -73,7 +78,9 @@
readState.readExternal(element);
BlazeAndroidRunConfigurationCommonState readCommonState = readState.getCommonState();
- assertThat(readCommonState.getUserFlags()).containsExactly("--flag1", "--flag2").inOrder();
+ assertThat(readCommonState.getBlazeFlagsState().getRawFlags())
+ .containsExactly("--flag1", "--flag2")
+ .inOrder();
assertThat(readCommonState.isNativeDebuggingEnabled()).isTrue();
assertThat(readState.getTestingType())
@@ -96,7 +103,8 @@
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
BlazeAndroidRunConfigurationCommonState readCommonState = readState.getCommonState();
- assertThat(readCommonState.getUserFlags()).isEqualTo(commonState.getUserFlags());
+ assertThat(readCommonState.getBlazeFlagsState().getRawFlags())
+ .isEqualTo(commonState.getBlazeFlagsState().getRawFlags());
assertThat(readCommonState.isNativeDebuggingEnabled())
.isEqualTo(commonState.isNativeDebuggingEnabled());
@@ -115,7 +123,7 @@
final XMLOutputter xmlOutputter = new XMLOutputter(Format.getCompactFormat());
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
- commonState.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
+ commonState.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
commonState.setNativeDebuggingEnabled(true);
state.setTestingType(BlazeAndroidTestRunConfigurationState.TEST_METHOD);
@@ -140,7 +148,7 @@
RunConfigurationStateEditor editor = state.getEditor(getProject());
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
- commonState.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
+ commonState.getBlazeFlagsState().setRawFlags(ImmutableList.of("--flag1", "--flag2"));
commonState.setNativeDebuggingEnabled(true);
state.setTestingType(BlazeAndroidTestRunConfigurationState.TEST_METHOD);
@@ -158,7 +166,8 @@
editor.applyEditorTo(readState);
BlazeAndroidRunConfigurationCommonState readCommonState = readState.getCommonState();
- assertThat(readCommonState.getUserFlags()).isEqualTo(commonState.getUserFlags());
+ assertThat(readCommonState.getBlazeFlagsState().getRawFlags())
+ .isEqualTo(commonState.getBlazeFlagsState().getRawFlags());
assertThat(readCommonState.isNativeDebuggingEnabled())
.isEqualTo(commonState.isNativeDebuggingEnabled());
@@ -184,7 +193,8 @@
BlazeAndroidRunConfigurationCommonState commonState = state.getCommonState();
BlazeAndroidRunConfigurationCommonState readCommonState = readState.getCommonState();
- assertThat(readCommonState.getUserFlags()).isEqualTo(commonState.getUserFlags());
+ assertThat(readCommonState.getBlazeFlagsState().getRawFlags())
+ .isEqualTo(commonState.getBlazeFlagsState().getRawFlags());
assertThat(readCommonState.isNativeDebuggingEnabled())
.isEqualTo(commonState.isNativeDebuggingEnabled());
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..e888374 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,8 @@
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.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;
@@ -29,14 +30,18 @@
import com.intellij.psi.search.GlobalSearchScope;
import javax.annotation.Nullable;
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
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..a712648
--- /dev/null
+++ b/aswb/tests/integrationtests/com/google/idea/blaze/android/sync/AndroidSyncTest.java
@@ -0,0 +1,398 @@
+/*
+ * 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.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.CIdeInfo;
+import com.google.idea.blaze.base.ideinfo.CToolchainIdeInfo;
+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.ExecutionRootPath;
+import com.google.idea.blaze.base.model.primitives.Kind;
+import com.google.idea.blaze.base.model.primitives.LanguageClass;
+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.google.idea.blaze.base.sync.projectstructure.ModuleFinder;
+import com.google.idea.blaze.cpp.BlazeCWorkspace;
+import com.google.idea.blaze.java.sync.BlazeJavaSyncAugmenter;
+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 com.jetbrains.cidr.lang.OCLanguageKind;
+import com.jetbrains.cidr.lang.workspace.OCResolveConfiguration;
+import com.jetbrains.cidr.lang.workspace.OCWorkspace;
+import com.jetbrains.cidr.lang.workspace.OCWorkspaceManager;
+import com.jetbrains.cidr.lang.workspace.compiler.OCCompilerSettings;
+import java.util.Arrays;
+import java.util.List;
+import org.jetbrains.android.facet.AndroidFacet;
+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");
+ registerProjectService(OCWorkspaceManager.class, new MockOCWorkspaceManager());
+ }
+
+ 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 testAndroidSyncAugmenterPresent() {
+ assertThat(
+ Arrays.stream(BlazeJavaSyncAugmenter.EP_NAME.getExtensions())
+ .anyMatch(e -> e instanceof BlazeAndroidJavaSyncAugmenter))
+ .isTrue();
+ }
+
+ @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"))
+ .setResourceJavaPackage("com.google")
+ .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 =
+ ModuleFinder.getInstance(getProject())
+ .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME);
+ assertThat(workspaceModule).isNotNull();
+ assertThat(AndroidFacet.getInstance(workspaceModule)).isNotNull();
+
+ // Check that a resource module was created
+ Module resourceModule =
+ ModuleFinder.getInstance(getProject()).findModuleByName("java.com.google.lib");
+ assertThat(resourceModule).isNotNull();
+ assertThat(AndroidFacet.getInstance(resourceModule)).isNotNull();
+ }
+
+ @Test
+ public void testMultipleToolchainsNoIssue() {
+ // Test what happens if there are multiple toolchains in the target map
+ // (e.g., from --fat_apk_cpu)
+ setProjectView(
+ "directories:",
+ " java/com/google",
+ "targets:",
+ " //java/com/google:app",
+ "additional_languages:",
+ " c",
+ "android_sdk_platform: android-25");
+ workspace.createDirectory(new WorkspacePath("java/com/google"));
+ 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 {}");
+
+ workspace.createFile(new WorkspacePath("java/com/google/jni/native.cc"), "void foo() {}");
+ workspace.createFile(new WorkspacePath("java/com/google/jni/native2.cc"), "void bar() {}");
+
+ TargetMap targetMap =
+ TargetMapBuilder.builder()
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setBuildFile(sourceRoot("android_ndk_linux/toolchains/BUILD"))
+ .setLabel("//android_ndk_linux/toolchains:armv7a")
+ .setKind(Kind.CC_TOOLCHAIN)
+ .setCToolchainInfo(
+ CToolchainIdeInfo.builder()
+ .setTargetName("arm-linux-androideabi")
+ .setCppExecutable(
+ new ExecutionRootPath("bin/arm-linux-androideabi-gcc"))
+ .setPreprocessorExecutable(
+ new ExecutionRootPath("bin/arm-linux-androideabi-cpp"))
+ .addBaseCompilerOptions(
+ ImmutableList.of(
+ "-DOS_ANDROID",
+ "-mbionic",
+ "-ffunction-sections",
+ "-march=armv7-a",
+ "-mfpu=vfpv3-d16"))
+ .addCppCompilerOptions(ImmutableList.of("-std=gnu++11"))
+ .addBuiltInIncludeDirectories(
+ ImmutableList.of(
+ new ExecutionRootPath(
+ "lib/gcc/arm-linux-androideabi/4.8/include")))
+ .addLinkOptions(
+ ImmutableList.of(
+ "--sysroot=android_ndk_linux/platforms/android-18/arch-arm"))
+ .addUnfilteredCompilerOptions(
+ ImmutableList.of(
+ "--sysroot=android_ndk_linux/platforms/android-18/arch-arm"))
+ .addUnfilteredToolchainSystemIncludes(
+ ImmutableList.of(
+ new ExecutionRootPath(
+ "android_ndk_linux/sources/llvm-libc++/libcxx/include")))))
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setBuildFile(sourceRoot("android_ndk_linux/toolchains/BUILD"))
+ .setLabel("//android_ndk_linux/toolchains:aarch64")
+ .setKind(Kind.CC_TOOLCHAIN)
+ .setCToolchainInfo(
+ CToolchainIdeInfo.builder()
+ .setTargetName("aarch64-linux-android")
+ .setCppExecutable(
+ new ExecutionRootPath("prebuilt/bin/aarch64-linux-android-gcc"))
+ .setPreprocessorExecutable(
+ new ExecutionRootPath("prebuilt/bin/aarch64-linux-android-cpp"))
+ .addBaseCompilerOptions(
+ ImmutableList.of("-DOS_ANDROID", "-mbionic", "-ffunction-sections"))
+ .addCppCompilerOptions(ImmutableList.of("-std=gnu++11"))
+ .addBuiltInIncludeDirectories(
+ ImmutableList.of(
+ new ExecutionRootPath(
+ "lib/gcc/aarch64-linux-android/4.9/include")))
+ .addLinkOptions(
+ ImmutableList.of(
+ "--sysroot=android_ndk_linux/platforms/android-21/arch-arm64"))
+ .addUnfilteredCompilerOptions(
+ ImmutableList.of(
+ "--sysroot=android_ndk_linux/platforms/android-21/arch-arm64"))
+ .addUnfilteredToolchainSystemIncludes(
+ ImmutableList.of(
+ new ExecutionRootPath(
+ "android_ndk_linux/sources/llvm-libc++/libcxx/include")))))
+ .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"))
+ .setResourceJavaPackage("com.google")
+ .setGenerateResourceClass(true))
+ .addSource(sourceRoot("java/com/google/Other.java")))
+ // Technically, blaze returns multiple instances of native libs (one for each CPU from
+ // fat APK). However, we just pick the first instance we run into for the target map.
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setBuildFile(sourceRoot("java/com/google/BUILD"))
+ .setLabel("//java/com/google:native_lib")
+ .setKind("cc_library")
+ .setCInfo(
+ CIdeInfo.builder()
+ .addTransitiveQuoteIncludeDirectories(
+ ImmutableList.of(
+ new ExecutionRootPath("."),
+ new ExecutionRootPath("blaze-out/android-aarch64-etc/genfiles"),
+ new ExecutionRootPath(
+ "blaze-out/android-aarch64-etc/genfiles/third_party/java")))
+ .addTransitiveSystemIncludeDirectories(
+ ImmutableList.of(
+ new ExecutionRootPath("third_party/stl/gcc3"),
+ new ExecutionRootPath("third_party/java/jdk/include"))))
+ .addSource(sourceRoot("java/com/google/jni/native.cc"))
+ .addDependency("//android_ndk_linux/toolchains:aarch64"))
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setBuildFile(sourceRoot("java/com/google/BUILD"))
+ .setLabel("//java/com/google:native_lib2")
+ .setKind("cc_library")
+ .setCInfo(
+ CIdeInfo.builder()
+ .addTransitiveQuoteIncludeDirectories(
+ ImmutableList.of(
+ new ExecutionRootPath("."),
+ new ExecutionRootPath("blaze-out/android-aarch64-etc/genfiles"),
+ new ExecutionRootPath(
+ "blaze-out/android-aarch64-etc/genfiles/third_party/java")))
+ .addTransitiveSystemIncludeDirectories(
+ ImmutableList.of(
+ new ExecutionRootPath("third_party/stl/gcc3"),
+ new ExecutionRootPath("third_party/java/jdk/include"))))
+ .addSource(sourceRoot("java/com/google/jni/native2.cc"))
+ .addDependency("//java/com/google:native_lib")
+ .addDependency("//android_ndk_linux/toolchains:armv7a"))
+ // Other targets like android_binary and android_test might also depend on
+ // a cc_toolchain.
+ .addTarget(
+ TargetIdeInfo.builder()
+ .setBuildFile(sourceRoot("java/com/google/BUILD"))
+ .setLabel("//java/com/google:app")
+ .setKind("android_binary")
+ .setAndroidInfo(
+ AndroidIdeInfo.builder()
+ .setManifestFile(sourceRoot("java/com/google/AndroidManifest.xml"))
+ .setResourceJavaPackage("com.google")
+ .setGenerateResourceClass(true))
+ .addSource(sourceRoot("java/com/google/Source.java"))
+ .addDependency("//tools/jdk:toolchain")
+ .addDependency("//android_ndk_linux/toolchains:armv7a")
+ .addDependency("//java/com/google:lib")
+ .addDependency("//java/com/google:native_lib")
+ .addDependency("//java/com/google:native_lib2"))
+ .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);
+ assertThat(blazeProjectData.workspaceLanguageSettings.isLanguageActive(LanguageClass.C))
+ .isTrue();
+
+ // Check that the workspace is set to android
+ Module workspaceModule =
+ ModuleFinder.getInstance(getProject())
+ .findModuleByName(BlazeDataStorage.WORKSPACE_MODULE_NAME);
+ assertThat(workspaceModule).isNotNull();
+ assertThat(AndroidFacet.getInstance(workspaceModule)).isNotNull();
+
+ // Check resolve configurations for the native code match the toolchain that was in
+ // the library's deps (not switched for some reason).
+ VirtualFile nativeCc =
+ fileSystem.findFile(
+ workspaceRoot
+ .fileForPath(new WorkspacePath("java/com/google/jni/native.cc"))
+ .getPath());
+ VirtualFile nativeCc2 =
+ fileSystem.findFile(
+ workspaceRoot
+ .fileForPath(new WorkspacePath("java/com/google/jni/native2.cc"))
+ .getPath());
+
+ List<? extends OCResolveConfiguration> resolveConfigurations =
+ OCWorkspaceManager.getWorkspace(getProject()).getConfigurationsForFile(nativeCc);
+ assertThat(resolveConfigurations).hasSize(1);
+ OCCompilerSettings compilerSettings = resolveConfigurations.get(0).getCompilerSettings();
+ List<String> compilerSwitches =
+ compilerSettings.getCompilerSwitches(OCLanguageKind.CPP, nativeCc).getCommandLineArgs();
+ assertThat(compilerSwitches)
+ .contains("--sysroot=android_ndk_linux/platforms/android-21/arch-arm64");
+
+ resolveConfigurations =
+ OCWorkspaceManager.getWorkspace(getProject()).getConfigurationsForFile(nativeCc2);
+ assertThat(resolveConfigurations).hasSize(1);
+ compilerSettings = resolveConfigurations.get(0).getCompilerSettings();
+ compilerSwitches =
+ compilerSettings.getCompilerSwitches(OCLanguageKind.CPP, nativeCc).getCommandLineArgs();
+ assertThat(compilerSwitches)
+ .contains("--sysroot=android_ndk_linux/platforms/android-18/arch-arm");
+ }
+
+ private class MockOCWorkspaceManager extends OCWorkspaceManager {
+
+ @Override
+ public OCWorkspace getWorkspace() {
+ return BlazeCWorkspace.getInstance(getProject());
+ }
+ }
+}
diff --git a/aswb/2.3/tests/integrationtests/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProviderIntegrationTest.java b/aswb/tests/integrationtests/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProviderIntegrationTest.java
similarity index 94%
rename from aswb/2.3/tests/integrationtests/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProviderIntegrationTest.java
rename to aswb/tests/integrationtests/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProviderIntegrationTest.java
index 0be0dc0..e784f6a 100644
--- a/aswb/2.3/tests/integrationtests/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProviderIntegrationTest.java
+++ b/aswb/tests/integrationtests/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProviderIntegrationTest.java
@@ -283,20 +283,21 @@
}
private TargetMap buildTargetMap() {
- Label mainResourceLibrary = new Label("//com/google/example:main");
- Label androidLibraryDependency = new Label("//com/google/example:android_lib");
- Label androidResourceDependency = new Label("//com/google/example:android_res");
- Label androidResourceDependency2 = new Label("//com/google/example:android_res2");
- Label transitiveResourceDependency = new Label("//com/google/example/transitive:android_res");
- Label javaDependency = new Label("//com/google/example:java");
- Label transitiveJavaDependency = new Label("//com/google/example/transitive:java");
- Label sharedJavaDependency = new Label("//com/google/example/shared:java");
- Label sharedJavaDependency2 = new Label("//com/google/example/shared2:java");
- Label importDependency = new Label("//com/google/example:import");
- Label transitiveImportDependency = new Label("//com/google/example/transitive:import");
- Label unrelatedJava = new Label("//com/google/unrelated:java");
- Label unrelatedAndroidLibrary = new Label("//com/google/unrelated:android_lib");
- Label unrelatedAndroidResource = new Label("//com/google/unrelated:android_res");
+ Label mainResourceLibrary = Label.create("//com/google/example:main");
+ Label androidLibraryDependency = Label.create("//com/google/example:android_lib");
+ Label androidResourceDependency = Label.create("//com/google/example:android_res");
+ Label androidResourceDependency2 = Label.create("//com/google/example:android_res2");
+ Label transitiveResourceDependency =
+ Label.create("//com/google/example/transitive:android_res");
+ Label javaDependency = Label.create("//com/google/example:java");
+ Label transitiveJavaDependency = Label.create("//com/google/example/transitive:java");
+ Label sharedJavaDependency = Label.create("//com/google/example/shared:java");
+ Label sharedJavaDependency2 = Label.create("//com/google/example/shared2:java");
+ Label importDependency = Label.create("//com/google/example:import");
+ Label transitiveImportDependency = Label.create("//com/google/example/transitive:import");
+ Label unrelatedJava = Label.create("//com/google/unrelated:java");
+ Label unrelatedAndroidLibrary = Label.create("//com/google/unrelated:android_lib");
+ Label unrelatedAndroidResource = Label.create("//com/google/unrelated:android_res");
AndroidResourceModuleRegistry registry = new AndroidResourceModuleRegistry();
registry.put(
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java b/aswb/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java
similarity index 96%
rename from aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java
rename to aswb/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java
index fbd398d..283773a 100755
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java
+++ b/aswb/tests/unittests/com/google/idea/blaze/android/project/BlazeBuildSystemServiceTest.java
@@ -122,7 +122,7 @@
PsiFile psiFile = mock(PsiFile.class);
BuildReferenceManager buildReferenceManager = BuildReferenceManager.getInstance(project);
- when(buildReferenceManager.resolveLabel(new Label("//foo:bar"))).thenReturn(buildTargetPsi);
+ when(buildReferenceManager.resolveLabel(Label.create("//foo:bar"))).thenReturn(buildTargetPsi);
when(buildTargetPsi.getContainingFile()).thenReturn(psiFile);
when(buildTargetPsi.getTextOffset()).thenReturn(1337);
@@ -149,7 +149,7 @@
@Test
public void testAddDependencyWithoutBuildTargetPsi() throws Exception {
// Can't find PSI for the target.
- when(BuildReferenceManager.getInstance(project).resolveLabel(new Label("//foo:bar")))
+ when(BuildReferenceManager.getInstance(project).resolveLabel(Label.create("//foo:bar")))
.thenReturn(null);
VirtualFile buildFile =
@@ -165,9 +165,9 @@
}
private void mockBlazeImportSettings(Container projectServices) {
- BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager(project);
+ BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager();
importSettingsManager.setImportSettings(
- new BlazeImportSettings("", "", "", "", "", Blaze.BuildSystem.Blaze));
+ new BlazeImportSettings("", "", "", "", Blaze.BuildSystem.Blaze));
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
}
@@ -195,7 +195,7 @@
AndroidResourceModuleRegistry moduleRegistry = new AndroidResourceModuleRegistry();
moduleRegistry.put(
module,
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//foo:bar"))).build());
+ AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo:bar"))).build());
projectServices.register(AndroidResourceModuleRegistry.class, moduleRegistry);
}
@@ -204,7 +204,7 @@
TargetMapBuilder.builder()
.addTarget(
TargetIdeInfo.builder()
- .setLabel(new Label("//foo:bar"))
+ .setLabel(Label.create("//foo:bar"))
.setBuildFile(ArtifactLocation.builder().setRelativePath("foo/BUILD").build())
.build())
.build();
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java b/aswb/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
similarity index 94%
rename from aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
rename to aswb/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
index efd77ea..18e44ee 100644
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
+++ b/aswb/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
@@ -23,11 +23,11 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.android.settings.BlazeAndroidUserSettings;
import com.google.idea.blaze.base.BlazeTestCase;
+import com.google.idea.blaze.base.logging.EventLogger;
import com.google.idea.blaze.base.model.BlazeProjectData;
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,13 +59,13 @@
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));
+ new BlazeImportSettings("", "", "", "", BuildSystem.Blaze));
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
- projectServices.register(
- BlazeImportSettingsManagerLegacy.class, new BlazeImportSettingsManagerLegacy(project));
+ registerExtensionPoint(
+ ExtensionPointName.create("com.google.idea.blaze.EventLogger"), EventLogger.class);
ExtensionPoint<FeatureEnableService> extensionPoint =
registerExtensionPoint(
ExtensionPointName.create("com.android.project.featureEnableService"),
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java b/aswb/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java
similarity index 94%
rename from aswb/2.3/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java
rename to aswb/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java
index ffe8267..2b49d8c 100644
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/rendering/BlazeRenderErrorContributorTest.java
+++ b/aswb/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);
- BlazeImportSettings settings = new BlazeImportSettings("", "", "", "", "", BuildSystem.Blaze);
+ 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);
@@ -345,14 +342,14 @@
}
private void createTargetMapWithGeneratedResources() {
- Label mainResourcesTarget = new Label("//com/google/example:main");
- Label dependencyGeneratedResourceTarget = new Label("//com/google/example:generated");
- Label dependencySourceResourceTarget = new Label("//com/google/example:source");
+ Label mainResourcesTarget = Label.create("//com/google/example:main");
+ Label dependencyGeneratedResourceTarget = Label.create("//com/google/example:generated");
+ Label dependencySourceResourceTarget = Label.create("//com/google/example:source");
Label transitiveGeneratedResourcesTarget =
- new Label("//com/google/example/transitive:generated");
- Label transitiveSourceResourceTarget = new Label("//com/google/example/transitive:source");
- Label unrelatedGeneratedResourceTarget = new Label("//com/google/unrelated:generated");
- Label unrelatedSourceResourceTarget = new Label("//com/google/unrelated:source");
+ Label.create("//com/google/example/transitive:generated");
+ Label transitiveSourceResourceTarget = Label.create("//com/google/example/transitive:source");
+ Label unrelatedGeneratedResourceTarget = Label.create("//com/google/unrelated:generated");
+ Label unrelatedSourceResourceTarget = Label.create("//com/google/unrelated:source");
ArtifactLocation mainGeneratedResource =
artifact("com/google/example/main/generated/res", false);
@@ -500,7 +497,7 @@
}
private void createTargetMapWithNonStandardAndroidManifestName() {
- Label mainResourceTarget = new Label("//com/google/example:main");
+ Label mainResourceTarget = Label.create("//com/google/example:main");
ArtifactLocation mainManifest = artifact("com/google/example/main/WeirdManifest.xml", true);
ArtifactLocation mainResource = artifact("com/google/example/main/res", true);
@@ -530,8 +527,8 @@
}
private void createTargetMapWithNonStandardAndroidManifestNameInDependency() {
- Label mainResourceTarget = new Label("//com/google/example:main");
- Label dependencyResourceTarget = new Label("//com/google/example:dependency");
+ Label mainResourceTarget = Label.create("//com/google/example:main");
+ Label dependencyResourceTarget = Label.create("//com/google/example:dependency");
ArtifactLocation mainManifest = artifact("com/google/example/main/AndroidManifest.xml", true);
ArtifactLocation mainResource = artifact("com/google/example/main/res", true);
@@ -582,11 +579,11 @@
}
private void createTargetMapWithMissingClassDependency() {
- Label parentTarget = new Label("//com/google/example:app");
- Label independentLibraryTarget = new Label("//com/google/example/independent:library");
- Label independentLibrary2Target = new Label("//com/google/example/independent:library2");
- Label dependentLibraryTarget = new Label("//com/google/example/dependent:library");
- Label resourcesTarget = new Label("//com/google/example:resources");
+ Label parentTarget = Label.create("//com/google/example:app");
+ Label independentLibraryTarget = Label.create("//com/google/example/independent:library");
+ Label independentLibrary2Target = Label.create("//com/google/example/independent:library2");
+ Label dependentLibraryTarget = Label.create("//com/google/example/dependent:library");
+ Label resourcesTarget = Label.create("//com/google/example:resources");
ArtifactLocation manifest = artifact("com/google/example/AndroidManifest.xml", true);
ArtifactLocation resources = artifact("com/google/example/res", true);
@@ -667,15 +664,15 @@
ImmutableMap<File, TargetKey> sourceToTarget =
ImmutableMap.of(
VfsUtilCore.virtualToIoFile(independentLibraryView),
- TargetKey.forPlainTarget(new Label("//com/google/example/independent:library")),
+ TargetKey.forPlainTarget(Label.create("//com/google/example/independent:library")),
VfsUtilCore.virtualToIoFile(independentLibraryView2),
- TargetKey.forPlainTarget(new Label("//com/google/example/independent:library")),
+ TargetKey.forPlainTarget(Label.create("//com/google/example/independent:library")),
VfsUtilCore.virtualToIoFile(independentLibrary2View),
- TargetKey.forPlainTarget(new Label("//com/google/example/independent:library2")),
+ TargetKey.forPlainTarget(Label.create("//com/google/example/independent:library2")),
VfsUtilCore.virtualToIoFile(dependentLibraryView),
- TargetKey.forPlainTarget(new Label("//com/google/example/dependent:library")),
+ TargetKey.forPlainTarget(Label.create("//com/google/example/dependent:library")),
VfsUtilCore.virtualToIoFile(resourceView),
- TargetKey.forPlainTarget(new Label("//com/google/example:resources")));
+ TargetKey.forPlainTarget(Label.create("//com/google/example:resources")));
projectServices.register(
JavaPsiFacade.class, new MockJavaPsiFacade(project, psiManager, classes));
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java b/aswb/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java
similarity index 91%
rename from aswb/2.3/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java
rename to aswb/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java
index 86c20cf..b48fe02 100644
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java
+++ b/aswb/tests/unittests/com/google/idea/blaze/android/run/testrecorder/BlazeConfigurationsTest.java
@@ -23,7 +23,6 @@
import com.android.tools.idea.run.editor.ShowChooserTargetProvider;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
import com.google.gct.testrecorder.run.TestRecorderRunConfigurationProxy;
import com.google.gct.testrecorder.run.TestRecorderRunConfigurationProxyProvider;
import com.google.gct.testrecorder.ui.TestRecorderAction;
@@ -33,6 +32,7 @@
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.bazel.WorkspaceRootProvider;
+import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.RuleDefinition;
import com.google.idea.blaze.base.model.BlazeVersionData;
@@ -151,7 +151,7 @@
BlazeCommandRunConfigurationType.getInstance()
.getFactory()
.createTemplateConfiguration(project);
- blazeConfiguration.setTarget(new Label("//label:android_binary_rule"));
+ blazeConfiguration.setTarget(Label.create("//label:android_binary_rule"));
BlazeAndroidBinaryRunConfigurationState configurationState =
((BlazeAndroidBinaryRunConfigurationHandler) blazeConfiguration.getHandler()).getState();
configurationState.setMode(BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY);
@@ -164,9 +164,9 @@
}
private void mockBlazeImportSettings(Container projectServices) {
- BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager(project);
+ BlazeImportSettingsManager importSettingsManager = new BlazeImportSettingsManager();
importSettingsManager.setImportSettings(
- new BlazeImportSettings("", "", "", "", "", Blaze.BuildSystem.Blaze));
+ new BlazeImportSettings("", "", "", "", Blaze.BuildSystem.Blaze));
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
}
@@ -178,12 +178,12 @@
BlazeCommandRunConfiguration blazeAndroidBinaryConfiguration =
configurationFactory.createTemplateConfiguration(project);
blazeAndroidBinaryConfiguration.setName("AndroidBinaryConfiguration");
- blazeAndroidBinaryConfiguration.setTarget(new Label("//label:android_binary_rule"));
+ blazeAndroidBinaryConfiguration.setTarget(Label.create("//label:android_binary_rule"));
BlazeCommandRunConfiguration blazeAndroidTestConfiguration =
configurationFactory.createTemplateConfiguration(project);
blazeAndroidTestConfiguration.setName("AndroidTestConfiguration");
- blazeAndroidTestConfiguration.setTarget(new Label("//label:android_test_rule"));
+ blazeAndroidTestConfiguration.setTarget(Label.create("//label:android_test_rule"));
runManager.addConfiguration(
runManager.createConfiguration(blazeAndroidBinaryConfiguration, configurationFactory),
@@ -192,7 +192,7 @@
runManager.createConfiguration(blazeAndroidTestConfiguration, configurationFactory), true);
}
- private class MockTargetFinder extends TargetFinder {
+ private static class MockTargetFinder extends TargetFinder {
@Override
public List<TargetIdeInfo> findTargets(Project project, Predicate<TargetIdeInfo> predicate) {
return null;
@@ -201,9 +201,9 @@
@Override
public TargetIdeInfo targetForLabel(Project project, final Label label) {
TargetIdeInfo.Builder builder = TargetIdeInfo.builder().setLabel(label);
- if (label.equals(new Label("//label:android_binary_rule"))) {
+ if (label.equals(Label.create("//label:android_binary_rule"))) {
builder.setKind(Kind.ANDROID_BINARY);
- } else if (label.equals(new Label("//label:android_test_rule"))) {
+ } else if (label.equals(Label.create("//label:android_test_rule"))) {
builder.setKind(Kind.ANDROID_TEST);
}
return builder.build();
@@ -236,7 +236,7 @@
@Override
public Module getModule() {
Label label = getLabel();
- if (label != null && label.equals(new Label("//label:android_binary_rule"))) {
+ if (label != null && label.equals(Label.create("//label:android_binary_rule"))) {
return mockModule;
}
@@ -244,13 +244,18 @@
}
}
- private class MockBuildSystemProvider implements BuildSystemProvider {
+ private static class MockBuildSystemProvider implements BuildSystemProvider {
@Override
public Blaze.BuildSystem buildSystem() {
return Blaze.BuildSystem.Blaze;
}
@Override
+ public String getBinaryPath() {
+ return "/usr/bin/blaze";
+ }
+
+ @Override
public WorkspaceRootProvider getWorkspaceRootProvider() {
return null;
}
@@ -266,6 +271,12 @@
return null;
}
+ @Nullable
+ @Override
+ public String getProjectViewDocumentationUrl() {
+ return null;
+ }
+
@Override
public boolean isBuildFile(String fileName) {
return false;
@@ -278,15 +289,15 @@
}
@Override
- public FileNameMatcher buildFileMatcher() {
- return null;
+ public ImmutableList<FileNameMatcher> buildLanguageFileTypeMatchers() {
+ return ImmutableList.of();
}
@Override
public void populateBlazeVersionData(
BuildSystem buildSystem,
WorkspaceRoot workspaceRoot,
- ImmutableMap<String, String> blazeInfo,
+ BlazeInfo blazeInfo,
BlazeVersionData.Builder builder) {}
}
}
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..e720a87 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
@@ -81,7 +81,7 @@
artifactLocation -> new File("/", artifactLocation.getRelativePath());
private static final BlazeImportSettings DUMMY_IMPORT_SETTINGS =
- new BlazeImportSettings("", "", "", "", "", BuildSystem.Blaze);
+ new BlazeImportSettings("", "", "", "", BuildSystem.Blaze);
private BlazeContext context;
private ErrorCollector errorCollector = new ErrorCollector();
@@ -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();
@@ -221,7 +220,7 @@
assertThat(result.androidResourceModules)
.containsExactly(
AndroidResourceModule.builder(
- TargetKey.forPlainTarget(new Label("//java/apps/example:example_debug")))
+ TargetKey.forPlainTarget(Label.create("//java/apps/example:example_debug")))
.addResourceAndTransitiveResource(source("java/apps/example/res"))
.addTransitiveResource(source("java/apps/example/lib0/res"))
.addTransitiveResource(source("java/apps/example/lib1/res"))
@@ -231,7 +230,7 @@
.addTransitiveResourceDependency("//java/libraries/shared:shared")
.build(),
AndroidResourceModule.builder(
- TargetKey.forPlainTarget(new Label("//java/apps/example/lib0:lib0")))
+ TargetKey.forPlainTarget(Label.create("//java/apps/example/lib0:lib0")))
.addResourceAndTransitiveResource(source("java/apps/example/lib0/res"))
.addTransitiveResource(source("java/apps/example/lib1/res"))
.addTransitiveResource(source("java/libraries/shared/res"))
@@ -239,7 +238,7 @@
.addTransitiveResourceDependency("//java/libraries/shared:shared")
.build(),
AndroidResourceModule.builder(
- TargetKey.forPlainTarget(new Label("//java/apps/example/lib1:lib1")))
+ TargetKey.forPlainTarget(Label.create("//java/apps/example/lib1:lib1")))
.addResourceAndTransitiveResource(source("java/apps/example/lib1/res"))
.addTransitiveResource(source("java/libraries/shared/res"))
.addTransitiveResourceDependency("//java/libraries/shared:shared")
@@ -468,7 +467,7 @@
.setKind("android_library")
.setAndroidInfo(
AndroidIdeInfo.builder()
- .setLegacyResources(new Label("//java/example:resources"))
+ .setLegacyResources(Label.create("//java/example:resources"))
.setManifestFile(source("java/example/AndroidManifest.xml"))
.addResource(source("java/example/res"))
.setGenerateResourceClass(true)
@@ -492,7 +491,7 @@
assertThat(result.androidResourceModules)
.containsExactly(
AndroidResourceModule.builder(
- TargetKey.forPlainTarget(new Label("//java/example:resources")))
+ TargetKey.forPlainTarget(Label.create("//java/example:resources")))
.addResourceAndTransitiveResource(source("java/example/res"))
.build());
}
@@ -588,7 +587,8 @@
assertThat(result.androidResourceModules)
.containsExactly(
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//java/example:lib")))
+ AndroidResourceModule.builder(
+ TargetKey.forPlainTarget(Label.create("//java/example:lib")))
.addResourceAndTransitiveResource(source("java/example/res"))
.build());
}
@@ -654,7 +654,8 @@
errorCollector.assertNoIssues();
assertThat(result.androidResourceModules)
.containsExactly(
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//java/example:lib")))
+ AndroidResourceModule.builder(
+ TargetKey.forPlainTarget(Label.create("//java/example:lib")))
.addResourceAndTransitiveResource(source("java/example/res"))
.addResourceAndTransitiveResource(gen("java/example/res"))
.build());
@@ -759,7 +760,7 @@
assertThat(result.androidResourceModules)
.containsExactly(
AndroidResourceModule.builder(
- TargetKey.forPlainTarget(new Label("//java/uninterestingdir:lib")))
+ TargetKey.forPlainTarget(Label.create("//java/uninterestingdir:lib")))
.addResourceAndTransitiveResource(source("java/uninterestingdir/res"))
.build());
}
diff --git a/aswb/tests/unittests/com/google/idea/blaze/android/sync/importer/model/idea/AndroidResourceModuleRegistryTest.java b/aswb/tests/unittests/com/google/idea/blaze/android/sync/importer/model/idea/AndroidResourceModuleRegistryTest.java
index 9a8e66c..f21c480 100644
--- a/aswb/tests/unittests/com/google/idea/blaze/android/sync/importer/model/idea/AndroidResourceModuleRegistryTest.java
+++ b/aswb/tests/unittests/com/google/idea/blaze/android/sync/importer/model/idea/AndroidResourceModuleRegistryTest.java
@@ -51,11 +51,13 @@
Module moduleTwo = mock(Module.class);
Module moduleThree = mock(Module.class);
AndroidResourceModule resourceModuleOne =
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//foo/bar:one"))).build();
+ AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:one")))
+ .build();
AndroidResourceModule resourceModuleTwo =
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//foo/bar:two"))).build();
+ AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:two")))
+ .build();
AndroidResourceModule resourceModuleThree =
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//foo/bar:three")))
+ AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:three")))
.build();
registry.put(moduleOne, resourceModuleOne);
registry.put(moduleTwo, resourceModuleTwo);
@@ -76,9 +78,11 @@
public void testPutSameKeyDifferentValues() {
Module module = mock(Module.class);
AndroidResourceModule resourceModuleOne =
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//foo/bar:one"))).build();
+ AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:one")))
+ .build();
AndroidResourceModule resourceModuleTwo =
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//foo/bar:two"))).build();
+ AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:two")))
+ .build();
registry.put(module, resourceModuleOne);
registry.put(module, resourceModuleTwo);
assertThat(registry.get(module)).isEqualTo(resourceModuleTwo);
@@ -89,7 +93,8 @@
Module moduleOne = mock(Module.class);
Module moduleTwo = mock(Module.class);
AndroidResourceModule resourceModule =
- AndroidResourceModule.builder(TargetKey.forPlainTarget(new Label("//foo/bar:one"))).build();
+ AndroidResourceModule.builder(TargetKey.forPlainTarget(Label.create("//foo/bar:one")))
+ .build();
registry.put(moduleOne, resourceModule);
try {
registry.put(moduleTwo, resourceModule);
diff --git a/aswb/2.3/tests/utils/integration/com/google/idea/blaze/android/BlazeAndroidIntegrationTestCase.java b/aswb/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/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/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/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/resources/binaries/bazel-buildifier b/base/resources/binaries/bazel-buildifier
index c7347bb..9b5f6b0 100755
--- a/base/resources/binaries/bazel-buildifier
+++ b/base/resources/binaries/bazel-buildifier
Binary files differ
diff --git a/base/src/META-INF/blaze-base.xml b/base/src/META-INF/blaze-base.xml
index 913bdb5..f472193 100644
--- a/base/src/META-INF/blaze-base.xml
+++ b/base/src/META-INF/blaze-base.xml
@@ -56,12 +56,20 @@
class="com.google.idea.blaze.base.settings.ui.OpenLocalProjectViewAction"
text="Open Local Project View File">
</action>
- <action class="com.google.idea.blaze.base.buildmap.OpenCorrespondingBuildFile"
- id="Blaze.OpenCorrespondingBuildFile"
+ <action id="Blaze.AddDirectoryToProjectView"
+ class="com.google.idea.blaze.base.settings.ui.AddDirectoryToProjectAction"
+ text="Add Directory To Project...">
+ </action>
+ <action id="Blaze.OpenCorrespondingBuildFile"
+ class="com.google.idea.blaze.base.buildmap.OpenCorrespondingBuildFile"
text="Open Corresponding BUILD File">
</action>
- <action class="com.google.idea.blaze.base.sync.actions.PartialSyncAction"
- id="Blaze.PartialSync"
+ <action id="Blaze.CopyBlazeTargetPathAction"
+ class="com.google.idea.blaze.base.actions.CopyBlazeTargetPathAction"
+ text="Copy BUILD target string">
+ </action>
+ <action id="Blaze.PartialSync"
+ class="com.google.idea.blaze.base.sync.actions.PartialSyncAction"
text="Partially Sync File"
icon="BlazeIcons.Blaze">
</action>
@@ -77,12 +85,15 @@
class="com.google.idea.blaze.base.ide.NewBlazeRuleAction"
text="New Rule"
popup="true"/>
+ <action id="Blaze.OpenWorkspaceFile"
+ class="com.google.idea.blaze.base.ide.OpenBlazeWorkspaceFileAction"
+ text="Open Workspace File..."
+ icon="BlazeIcons.Blaze">
+ <add-to-group group-id="FileOpenGroup" relative-to-action="OpenFile" anchor="after"/>
+ </action>
<group id="Blaze.MainMenuActionGroup" class="com.google.idea.blaze.base.actions.BlazeMenuGroup">
<add-to-group group-id="MainMenu" anchor="before" relative-to-action="HelpMenu"/>
- <reference id="Blaze.EditLocalProjectView"/>
- <reference id="Blaze.EditProjectView"/>
- <separator/>
<group id ="Blaze.SyncMenuGroup" text="Sync" popup="true">
<reference id="Blaze.IncrementalSyncProject"/>
<reference id="Blaze.FullSyncProject"/>
@@ -95,6 +106,11 @@
<reference id="MakeBlazeProject"/>
<reference id="MakeBlazeModule"/>
</group>
+ <group id="Blaze.Project" text="Project" popup="true">
+ <reference id="Blaze.EditLocalProjectView"/>
+ <reference id="Blaze.EditProjectView"/>
+ <reference id="Blaze.AddDirectoryToProjectView"/>
+ </group>
<!--Add popup groups anchored after this bookmark-->
<group id="Blaze.MenuGroupsBookmark"/>
<separator/>
@@ -123,6 +139,7 @@
<separator/>
<reference ref="Blaze.PartialSync"/>
<reference ref="Blaze.OpenCorrespondingBuildFile"/>
+ <reference ref="Blaze.CopyBlazeTargetPathAction"/>
</group>
</actions>
@@ -162,8 +179,8 @@
serviceImplementation="com.google.idea.blaze.base.buildmodifier.FileSystemModifierImpl"/>
<applicationService serviceInterface="com.google.idea.blaze.base.run.targetfinder.TargetFinder"
serviceImplementation="com.google.idea.blaze.base.run.targetfinder.TargetFinderImpl"/>
- <applicationService serviceInterface="com.google.idea.blaze.base.command.info.BlazeInfo"
- serviceImplementation="com.google.idea.blaze.base.command.info.BlazeInfoImpl"/>
+ <applicationService serviceInterface="com.google.idea.blaze.base.command.info.BlazeInfoRunner"
+ serviceImplementation="com.google.idea.blaze.base.command.info.BlazeInfoRunnerImpl"/>
<treeStructureProvider implementation="com.google.idea.blaze.base.treeview.BlazeTreeStructureProvider" id="blaze"/>
@@ -183,12 +200,14 @@
<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"/>
<applicationService serviceInterface="com.google.idea.blaze.base.sync.projectstructure.ModuleEditorProvider"
serviceImplementation="com.google.idea.blaze.base.sync.projectstructure.ModuleEditorProviderImpl"/>
+ <projectService serviceInterface="com.google.idea.blaze.base.sync.projectstructure.ModuleFinder"
+ serviceImplementation="com.google.idea.blaze.base.sync.projectstructure.ModuleFinderImpl"/>
+ <applicationService serviceImplementation="com.google.idea.blaze.base.sync.projectview.RelatedWorkspacePathFinder"/>
<applicationService serviceInterface="com.google.idea.blaze.base.prefetch.PrefetchService"
serviceImplementation="com.google.idea.blaze.base.prefetch.PrefetchServiceImpl"/>
<applicationService serviceImplementation="com.google.idea.blaze.base.wizard2.BlazeWizardUserSettingsStorage"/>
@@ -225,6 +244,9 @@
<completion.contributor language="projectview" implementationClass="com.google.idea.blaze.base.lang.projectview.completion.WorkspaceTypeCompletionContributor"/>
<completion.contributor language="projectview" implementationClass="com.google.idea.blaze.base.lang.projectview.completion.AdditionalLanguagesCompletionContributor"/>
<enterHandlerDelegate implementation="com.google.idea.blaze.base.lang.projectview.formatting.ProjectViewEnterHandler"/>
+ <filetype.stubBuilder filetype="projectview" implementationClass="com.google.idea.blaze.base.lang.projectview.stubs.ProjectViewFileStubBuilder"/>
+ <lang.documentationProvider language="projectview" implementationClass="com.google.idea.blaze.base.lang.projectview.documentation.ProjectViewDocumentationProvider"/>
+ <langCodeStyleSettingsProvider implementation="com.google.idea.blaze.base.lang.projectview.formatting.ProjectViewCodeStyleSettingsProvider"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
@@ -233,10 +255,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"/>
@@ -257,6 +280,7 @@
<filetype.stubBuilder filetype="BUILD" implementationClass="com.google.idea.blaze.base.lang.buildfile.stubs.BuildFileStubBuilder"/>
<editorNotificationProvider implementation="com.google.idea.blaze.base.lang.AdditionalLanguagesHelper"/>
<usageTypeProvider implementation="com.google.idea.blaze.base.lang.buildfile.findusages.BuildUsageTypeProvider"/>
+ <renameInputValidator implementation="com.google.idea.blaze.base.lang.buildfile.refactor.TargetRenameValidator"/>
</extensions>
<extensions defaultExtensionNs="com.intellij.lang">
@@ -289,6 +313,9 @@
<interface-class>com.google.idea.common.experiments.ExperimentService</interface-class>
<implementation-class>com.google.idea.blaze.base.experiments.BlazeExperimentService</implementation-class>
</component>
+ <component>
+ <implementation-class>com.google.idea.blaze.base.prefetch.PrefetchProjectInitializer</implementation-class>
+ </component>
</application-components>
<project-components>
@@ -323,9 +350,11 @@
<extensionPoint qualifiedName="com.google.idea.blaze.AspectStrategyProvider" interface="com.google.idea.blaze.base.sync.aspects.strategy.AspectStrategyProvider"/>
<extensionPoint qualifiedName="com.google.idea.blaze.DistributedExecutorSupport" interface="com.google.idea.blaze.base.run.DistributedExecutorSupport"/>
<extensionPoint qualifiedName="com.google.idea.blaze.FileStringParser" interface="com.google.idea.blaze.base.run.filter.FileResolver"/>
- <extensionPoint qualifiedName="com.google.idea.blaze.BlazeTestXmlFinderStrategy" interface="com.google.idea.blaze.base.run.testlogs.BlazeTestXmlFinderStrategy"/>
+ <extensionPoint qualifiedName="com.google.idea.blaze.BlazeTestXmlFinderStrategy" interface="com.google.idea.blaze.base.run.testlogs.BlazeTestResultFinderStrategy"/>
<extensionPoint qualifiedName="com.google.idea.blaze.BlazeTestEventsHandler" interface="com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler"/>
<extensionPoint qualifiedName="com.google.idea.blaze.AttributeSpecificStringLiteralReferenceProvider" interface="com.google.idea.blaze.base.lang.buildfile.references.AttributeSpecificStringLiteralReferenceProvider"/>
+ <extensionPoint qualifiedName="com.google.idea.blaze.EventLogger" interface="com.google.idea.blaze.base.logging.EventLogger"/>
+ <extensionPoint qualifiedName="com.google.idea.blaze.ProjectViewDefaultValueProvider" interface="com.google.idea.blaze.base.projectview.section.ProjectViewDefaultValueProvider"/>
</extensionPoints>
<extensions defaultExtensionNs="com.google.idea.blaze">
@@ -339,13 +368,17 @@
<BuildSystemProvider implementation="com.google.idea.blaze.base.bazel.BazelBuildSystemProvider" order="last"/>
<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.TargetNameHeuristic" order="first" id="TargetNameHeuristic"/>
+ <TestTargetHeuristic implementation="com.google.idea.blaze.base.run.TestTargetSourcesHeuristic"/>
<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"/>
<FileStringParser implementation="com.google.idea.blaze.base.run.filter.StandardFileResolver" order="last"/>
- <BlazeTestXmlFinderStrategy implementation="com.google.idea.blaze.base.run.testlogs.TargetPathTestXmlFinderStrategy"/>
+ <BlazeTestXmlFinderStrategy implementation="com.google.idea.blaze.base.run.testlogs.TargetPathTestResultFinderStrategy"/>
<BlazeTestEventsHandler implementation="com.google.idea.blaze.base.run.smrunner.BlazeCompositeTestEventsHandler" order="last"/>
+ <ProjectViewDefaultValueProvider implementation="com.google.idea.blaze.base.projectview.section.sections.DirectorySection$DirectoriesProjectViewDefaultValueProvider"/>
+ <ProjectViewDefaultValueProvider implementation="com.google.idea.blaze.base.projectview.section.sections.TargetSection$TargetsProjectViewDefaultValueProvider"/>
+ <ProjectViewDefaultValueProvider implementation="com.google.idea.blaze.base.projectview.section.sections.AdditionalLanguagesSection$AdditionalLanguagesDefaultValueProvider"/>
</extensions>
</idea-plugin>
diff --git a/base/src/com/google/idea/blaze/base/actions/BlazeBuildService.java b/base/src/com/google/idea/blaze/base/actions/BlazeBuildService.java
index 6b9e095..36a23e9 100644
--- a/base/src/com/google/idea/blaze/base/actions/BlazeBuildService.java
+++ b/base/src/com/google/idea/blaze/base/actions/BlazeBuildService.java
@@ -37,7 +37,10 @@
import com.google.idea.blaze.base.scope.scopes.TimingScope;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.sync.aspects.BlazeIdeInterface;
+import com.google.idea.blaze.base.sync.aspects.BuildResult;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.base.sync.sharding.BlazeBuildTargetSharder;
+import com.google.idea.blaze.base.sync.sharding.BlazeBuildTargetSharder.ShardedTargetsResult;
import com.google.idea.blaze.base.util.SaveUtil;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
@@ -113,20 +116,31 @@
.push(notificationScope);
WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
- BlazeIdeInterface blazeIdeInterface = BlazeIdeInterface.getInstance();
SaveUtil.saveAllFiles();
- BlazeIdeInterface.BuildResult buildResult =
- blazeIdeInterface.compileIdeArtifacts(
+ ShardedTargetsResult shardedTargets =
+ BlazeBuildTargetSharder.expandAndShardTargets(
project,
context,
workspaceRoot,
projectViewSet,
- blazeProjectData.blazeVersionData,
+ blazeProjectData.workspacePathResolver,
targets);
+ if (shardedTargets.buildResult.status == BuildResult.Status.FATAL_ERROR) {
+ return;
+ }
+ BuildResult buildResult =
+ BlazeIdeInterface.getInstance()
+ .compileIdeArtifacts(
+ project,
+ context,
+ workspaceRoot,
+ projectViewSet,
+ blazeProjectData.blazeVersionData,
+ shardedTargets.shardedTargets);
FileCaches.refresh(project);
- if (buildResult != BlazeIdeInterface.BuildResult.SUCCESS) {
+ if (buildResult.status != BuildResult.Status.SUCCESS) {
context.setHasError();
}
}
diff --git a/base/src/com/google/idea/blaze/base/actions/BlazeMakeProjectAction.java b/base/src/com/google/idea/blaze/base/actions/BlazeMakeProjectAction.java
index a124759..b049dee 100644
--- a/base/src/com/google/idea/blaze/base/actions/BlazeMakeProjectAction.java
+++ b/base/src/com/google/idea/blaze/base/actions/BlazeMakeProjectAction.java
@@ -15,6 +15,8 @@
*/
package com.google.idea.blaze.base.actions;
+import com.google.common.collect.ImmutableMap;
+import com.google.idea.blaze.base.logging.EventLogger;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
@@ -22,6 +24,7 @@
@Override
protected void actionPerformedInBlazeProject(Project project, AnActionEvent e) {
+ EventLogger.getInstance().log(getClass(), "make", ImmutableMap.of());
BlazeBuildService.getInstance().buildProject(project);
}
}
diff --git a/base/src/com/google/idea/blaze/base/actions/CopyBlazeTargetPathAction.java b/base/src/com/google/idea/blaze/base/actions/CopyBlazeTargetPathAction.java
new file mode 100644
index 0000000..ffb49e9
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/actions/CopyBlazeTargetPathAction.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.base.actions;
+
+import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.common.actionhelper.ActionPresentationHelper;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.ide.CopyPasteManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import java.awt.datatransfer.StringSelection;
+import javax.annotation.Nullable;
+
+/** Copies a blaze target path into the clipboard */
+public class CopyBlazeTargetPathAction extends BlazeProjectAction {
+
+ @Override
+ protected void actionPerformedInBlazeProject(Project project, AnActionEvent e) {
+ Label label = getSelectedTarget(e);
+ if (label != null) {
+ CopyPasteManager.getInstance().setContents(new StringSelection(label.toString()));
+ }
+ }
+
+ @Override
+ protected void updateForBlazeProject(Project project, AnActionEvent e) {
+ Label label = getSelectedTarget(e);
+ ActionPresentationHelper.of(e).hideIf(label == null).commit();
+ }
+
+ @Nullable
+ private static Label getSelectedTarget(AnActionEvent e) {
+ PsiElement psiElement = e.getData(CommonDataKeys.PSI_ELEMENT);
+ if (!(psiElement instanceof FuncallExpression)) {
+ return null;
+ }
+ return ((FuncallExpression) psiElement).resolveBuildLabel();
+ }
+}
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/async/process/LineProcessingOutputStream.java b/base/src/com/google/idea/blaze/base/async/process/LineProcessingOutputStream.java
index 8aa44a8..5357fdf 100644
--- a/base/src/com/google/idea/blaze/base/async/process/LineProcessingOutputStream.java
+++ b/base/src/com/google/idea/blaze/base/async/process/LineProcessingOutputStream.java
@@ -15,11 +15,11 @@
*/
package com.google.idea.blaze.base.async.process;
-import com.google.common.collect.Lists;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.List;
-import org.jetbrains.annotations.NotNull;
/** An base output stream which marshals output into newline-delimited segments for processing. */
public final class LineProcessingOutputStream extends OutputStream {
@@ -31,25 +31,29 @@
*
* @return Whether line processing should continue
*/
- boolean processLine(@NotNull String line);
+ boolean processLine(String line);
}
- @NotNull private final StringBuffer stringBuffer = new StringBuffer();
+ private final StringBuffer stringBuffer = new StringBuffer();
private volatile boolean closed;
- @NotNull private final List<LineProcessor> lineProcessors;
+ private final ImmutableList<LineProcessor> lineProcessors;
- LineProcessingOutputStream(@NotNull LineProcessor... lineProcessors) {
- this.lineProcessors = Lists.newArrayList(lineProcessors);
+ LineProcessingOutputStream(ImmutableList<LineProcessor> lineProcessors) {
+ this.lineProcessors = lineProcessors;
}
- public static LineProcessingOutputStream of(@NotNull LineProcessor... lineProcessors) {
+ public static LineProcessingOutputStream of(LineProcessor... lineProcessors) {
+ return new LineProcessingOutputStream(ImmutableList.copyOf(lineProcessors));
+ }
+
+ public static LineProcessingOutputStream of(ImmutableList<LineProcessor> lineProcessors) {
return new LineProcessingOutputStream(lineProcessors);
}
@Override
public synchronized void write(byte[] b, int off, int len) {
if (!closed) {
- String text = new String(b, off, len);
+ String text = new String(b, off, len, UTF_8);
stringBuffer.append(text);
while (true) {
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..85296be 100644
--- a/base/src/com/google/idea/blaze/base/bazel/BazelBuildSystemProvider.java
+++ b/base/src/com/google/idea/blaze/base/bazel/BazelBuildSystemProvider.java
@@ -16,13 +16,15 @@
package com.google.idea.blaze.base.bazel;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.RuleDefinition;
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.ExtensionFileNameMatcher;
import com.intellij.openapi.fileTypes.FileNameMatcher;
import java.io.File;
import javax.annotation.Nullable;
@@ -35,6 +37,13 @@
return BuildSystem.Bazel;
}
+ @Nullable
+ @Override
+ public String getBinaryPath() {
+ BlazeUserSettings settings = BlazeUserSettings.getInstance();
+ return settings.getBazelBinaryPath();
+ }
+
@Override
public WorkspaceRootProvider getWorkspaceRootProvider() {
return BazelWorkspaceRootProvider.INSTANCE;
@@ -47,17 +56,20 @@
"bazel-bin", "bazel-genfiles", "bazel-out", "bazel-testlogs", "bazel-" + rootDir);
}
- @Nullable
@Override
public String getRuleDocumentationUrl(RuleDefinition rule) {
// TODO: URL pointing to specific BUILD rule.
return "http://www.bazel.build/docs/be/overview.html";
}
- // TODO: Update the methods below when https://github.com/bazelbuild/bazel/issues/552 lands.
+ @Override
+ public String getProjectViewDocumentationUrl() {
+ return "https://ij.bazel.build/docs/project-views.html";
+ }
+
@Override
public boolean isBuildFile(String fileName) {
- return fileName.equals("BUILD");
+ return fileName.equals("BUILD") || fileName.equals("BUILD.bazel");
}
@Nullable
@@ -65,22 +77,28 @@
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> buildLanguageFileTypeMatchers() {
+ return ImmutableList.of(
+ new ExactFileNameMatcher("BUILD"), new ExactFileNameMatcher("BUILD.bazel"),
+ new ExtensionFileNameMatcher("bzl"), new ExactFileNameMatcher("WORKSPACE"));
}
@Override
public void populateBlazeVersionData(
BuildSystem buildSystem,
WorkspaceRoot workspaceRoot,
- ImmutableMap<String, String> blazeInfo,
+ BlazeInfo blazeInfo,
BlazeVersionData.Builder builder) {
if (buildSystem != BuildSystem.Bazel) {
return;
diff --git a/base/src/com/google/idea/blaze/base/bazel/BazelVersion.java b/base/src/com/google/idea/blaze/base/bazel/BazelVersion.java
index 44582cb..19be022 100644
--- a/base/src/com/google/idea/blaze/base/bazel/BazelVersion.java
+++ b/base/src/com/google/idea/blaze/base/bazel/BazelVersion.java
@@ -21,7 +21,6 @@
import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.intellij.openapi.util.text.StringUtil;
import java.io.Serializable;
-import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
@@ -77,7 +76,7 @@
return new BazelVersion(major, minor, bugfix);
}
- public static BazelVersion parseVersion(Map<String, String> blazeInfo) {
+ public static BazelVersion parseVersion(BlazeInfo blazeInfo) {
return parseVersion(blazeInfo.get(BlazeInfo.RELEASE));
}
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..22392d4 100644
--- a/base/src/com/google/idea/blaze/base/bazel/BuildSystemProvider.java
+++ b/base/src/com/google/idea/blaze/base/bazel/BuildSystemProvider.java
@@ -16,7 +16,7 @@
package com.google.idea.blaze.base.bazel;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.RuleDefinition;
import com.google.idea.blaze.base.model.BlazeVersionData;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
@@ -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. */
@@ -80,6 +90,10 @@
@Nullable
String getRuleDocumentationUrl(RuleDefinition rule);
+ /** The URL providing documentation for project view files, if one can be found. */
+ @Nullable
+ String getProjectViewDocumentationUrl();
+
/** Check if the given filename is a valid BUILD file name. */
boolean isBuildFile(String fileName);
@@ -101,12 +115,13 @@
return buildFile != null ? directory.getFileSystem().findFileByPath(buildFile.getPath()) : null;
}
- FileNameMatcher buildFileMatcher();
+ /** Returns the list of file types recognized as build system files. */
+ ImmutableList<FileNameMatcher> buildLanguageFileTypeMatchers();
/** Populates the passed builder with version data. */
void populateBlazeVersionData(
BuildSystem buildSystem,
WorkspaceRoot workspaceRoot,
- ImmutableMap<String, String> blazeInfo,
+ BlazeInfo blazeInfo,
BlazeVersionData.Builder builder);
}
diff --git a/base/src/com/google/idea/blaze/base/buildmodifier/BuildifierDelegatingCodeStyleManager.java b/base/src/com/google/idea/blaze/base/buildmodifier/BuildifierDelegatingCodeStyleManager.java
index cf4574a..ca0827d 100644
--- a/base/src/com/google/idea/blaze/base/buildmodifier/BuildifierDelegatingCodeStyleManager.java
+++ b/base/src/com/google/idea/blaze/base/buildmodifier/BuildifierDelegatingCodeStyleManager.java
@@ -78,7 +78,7 @@
private static boolean overrideFormatterForFile(PsiFile file) {
// don't format skylark extensions
return file instanceof BuildFile
- && ((BuildFile) file).getBlazeFileType() == BlazeFileType.BuildPackage;
+ && ((BuildFile) file).getBlazeFileType() != BlazeFileType.SkylarkExtension;
}
private void formatInternal(PsiFile file, Collection<TextRange> ranges) {
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..d43aeaa 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,27 +41,11 @@
}
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.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);
- }
+ return ImmutableList.<String>builder()
+ .add(binaryPath)
+ .add(name.toString())
+ .addAll(arguments)
+ .build();
}
@Override
@@ -78,21 +53,20 @@
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 +83,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/BlazeFlags.java b/base/src/com/google/idea/blaze/base/command/BlazeFlags.java
index 1f24f62..a44b056 100644
--- a/base/src/com/google/idea/blaze/base/command/BlazeFlags.java
+++ b/base/src/com/google/idea/blaze/base/command/BlazeFlags.java
@@ -21,6 +21,8 @@
import com.google.idea.blaze.base.projectview.section.sections.BuildFlagsSection;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
+import com.google.idea.common.experiments.BoolExperiment;
+import com.intellij.execution.configurations.ParametersList;
import com.intellij.openapi.project.Project;
import com.intellij.util.PlatformUtils;
import java.util.List;
@@ -28,6 +30,9 @@
/** The collection of all the Bazel flag strings we use. */
public final class BlazeFlags {
+ private static final BoolExperiment macroExpandBuildFlags =
+ new BoolExperiment("macro.expand.blaze.flags", true);
+
// Build the maximum number of possible dependencies of the project and to show all the build
// errors in single go.
public static final String KEEP_GOING = "--keep_going";
@@ -39,6 +44,7 @@
public static final String JAVA_BINARY_DEBUG = "--wrapper_script_flag=--debug";
// Runs tests locally, in sequence (rather than parallel), and streams their results to stdout.
public static final String TEST_OUTPUT_STREAMED = "--test_output=streamed";
+ public static final String DISABLE_TEST_SHARDING = "--test_sharding_strategy=disabled";
// Filters the unit tests that are run (used with regexp for Java/Robolectric tests).
public static final String TEST_FILTER = "--test_filter";
// When used with mobile-install, deploys the an app incrementally.
@@ -48,9 +54,6 @@
public static final String SPLIT_APKS = "--split_apks";
// Re-run the test even if the results are cached.
public static final String NO_CACHE_TEST_RESULTS = "--nocache_test_results";
- // Avoids node GC between ide_build_info and blaze build
- public static final String VERSION_WINDOW_FOR_DIRTY_NODE_GC =
- "--version_window_for_dirty_node_gc=-1";
public static final String EXPERIMENTAL_SHOW_ARTIFACTS = "--experimental_show_artifacts";
@@ -60,7 +63,7 @@
for (BuildFlagsProvider buildFlagsProvider : BuildFlagsProvider.EP_NAME.getExtensions()) {
buildFlagsProvider.addBuildFlags(buildSystem, projectViewSet, flags);
}
- flags.addAll(projectViewSet.listItems(BuildFlagsSection.KEY));
+ flags.addAll(expandBuildFlags(projectViewSet.listItems(BuildFlagsSection.KEY)));
return flags;
}
@@ -90,5 +93,17 @@
return TOOL_TAG + platformPrefix;
}
+ /** Expands any macros in the passed build flags. */
+ public static List<String> expandBuildFlags(List<String> flags) {
+ if (!macroExpandBuildFlags.getValue()) {
+ return flags;
+ }
+ // This built-in IntelliJ class will do macro expansion using
+ // both your enviroment and your Settings > Behavior > Path Variables
+ ParametersList parametersList = new ParametersList();
+ parametersList.addAll(flags);
+ return parametersList.getList();
+ }
+
private BlazeFlags() {}
}
diff --git a/base/src/com/google/idea/blaze/base/command/BuildFlagsProviderImpl.java b/base/src/com/google/idea/blaze/base/command/BuildFlagsProviderImpl.java
index 2e40662..fcdfc70 100644
--- a/base/src/com/google/idea/blaze/base/command/BuildFlagsProviderImpl.java
+++ b/base/src/com/google/idea/blaze/base/command/BuildFlagsProviderImpl.java
@@ -15,26 +15,19 @@
*/
package com.google.idea.blaze.base.command;
-import static com.google.idea.blaze.base.command.BlazeFlags.VERSION_WINDOW_FOR_DIRTY_NODE_GC;
-
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
-import com.google.idea.common.experiments.BoolExperiment;
import java.util.List;
/** Flags added to blaze/bazel build commands. */
public class BuildFlagsProviderImpl implements BuildFlagsProvider {
- private static final BoolExperiment experimentUseVersionWindowForDirtyNodeGc =
- new BoolExperiment("ide_build_info.use_version_window_for_dirty_node_gc", false);
-
@Override
public void addBuildFlags(
BuildSystem buildSystem, ProjectViewSet projectViewSet, List<String> flags) {
- if (experimentUseVersionWindowForDirtyNodeGc.getValue()) {
- flags.add(VERSION_WINDOW_FOR_DIRTY_NODE_GC);
- }
flags.add("--curses=no");
flags.add("--color=no");
+ flags.add("--noexperimental_ui");
+ flags.add("--noprogress_in_terminal_title");
}
}
diff --git a/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java b/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java
deleted file mode 100644
index 8d512c0..0000000
--- a/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java
+++ /dev/null
@@ -1,64 +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.command;
-
-import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
-import java.io.File;
-import java.util.List;
-import java.util.function.Predicate;
-import org.jetbrains.annotations.NotNull;
-
-/** Collects the output of --experimental_show_artifacts */
-public class ExperimentalShowArtifactsLineProcessor
- implements LineProcessingOutputStream.LineProcessor {
- private static final String OUTPUT_START = "Build artifacts:";
- private static final String OUTPUT_MARKER = ">>>";
-
- private final List<File> fileList;
- private final Predicate<String> filter;
- boolean insideBuildResult = false;
-
- public ExperimentalShowArtifactsLineProcessor(List<File> fileList) {
- this(fileList, (value) -> true);
- }
-
- public ExperimentalShowArtifactsLineProcessor(List<File> fileList, Predicate<String> filter) {
- this.fileList = fileList;
- this.filter = filter;
- }
-
- @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 (!insideBuildResult) {
- insideBuildResult = line.equals(OUTPUT_START);
- }
- return !insideBuildResult;
- }
-}
diff --git a/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelper.java b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelper.java
new file mode 100644
index 0000000..9adf5e2
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelper.java
@@ -0,0 +1,65 @@
+/*
+ * 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.command.buildresult;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream.LineProcessor;
+import com.google.idea.common.experiments.BoolExperiment;
+import java.io.File;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.function.Predicate;
+
+/** Assists in getting build artifacts from a build operation. */
+public interface BuildResultHelper {
+ // This experiment does *not* work yet and should remain off
+ BoolExperiment USE_BEP = new BoolExperiment("use.bep", false);
+
+ /**
+ * Constructs a new build result helper.
+ *
+ * @param files A filter for the output artifacts you are interested in.
+ */
+ static BuildResultHelper forFiles(Predicate<String> files) {
+ return USE_BEP.getValue()
+ ? new BuildResultHelperBep(files)
+ : new BuildResultHelperStderr(files);
+ }
+
+ /**
+ * Returns the build flags necessary for the build result helper to work.
+ *
+ * <p>The user must add these flags to their build command.
+ */
+ List<String> getBuildFlags();
+
+ /**
+ * Returns an output stream to be passed to the external task's stderr.
+ *
+ * <p>The user must pipe blaze's stderr to this output stream.
+ *
+ * @param lineProcessors Any additional line processors you want on stderr output.
+ */
+ OutputStream stderr(LineProcessor... lineProcessors);
+
+ /**
+ * Returns the build result. May only be called once the build is complete, or no artifacts will
+ * be returned.
+ *
+ * @return The build artifacts from the build operation.
+ */
+ ImmutableList<File> getBuildArtifacts();
+}
diff --git a/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperBep.java b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperBep.java
new file mode 100644
index 0000000..8a32e85
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperBep.java
@@ -0,0 +1,98 @@
+/*
+ * 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.command.buildresult;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream.LineProcessor;
+import com.google.repackaged.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEvent;
+import com.google.repackaged.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId;
+import com.google.repackaged.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.IdCase;
+import com.intellij.openapi.diagnostic.Logger;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.UUID;
+import java.util.function.Predicate;
+
+/**
+ * Build event protocol implementation to get build results.
+ *
+ * <p>The build even protocol (BEP for short) is a proto-based protocol used by bazel to communicate
+ * build events.
+ */
+class BuildResultHelperBep implements BuildResultHelper {
+ private static final Logger logger = Logger.getInstance(BuildResultHelperBep.class);
+ private final File outputFile;
+ private final Predicate<String> fileFilter;
+ private ImmutableList<File> result;
+
+ BuildResultHelperBep(Predicate<String> fileFilter) {
+ this.fileFilter = fileFilter;
+ File tempDir = new File(System.getProperty("java.io.tmpdir"));
+ String suffix = UUID.randomUUID().toString();
+ String fileName = "intellij-bep-" + suffix;
+ this.outputFile = new File(tempDir, fileName);
+ }
+
+ @Override
+ public List<String> getBuildFlags() {
+ return ImmutableList.of("--experimental_build_event_binary_file=" + outputFile.getPath());
+ }
+
+ @Override
+ public OutputStream stderr(LineProcessor... lineProcessors) {
+ return LineProcessingOutputStream.of(ImmutableList.copyOf(lineProcessors));
+ }
+
+ @Override
+ public ImmutableList<File> getBuildArtifacts() {
+ if (result == null) {
+ result = readResult();
+ }
+ return result;
+ }
+
+ private ImmutableList<File> readResult() {
+ ImmutableList.Builder<File> result = ImmutableList.builder();
+ try (InputStream inputStream = new BufferedInputStream(new FileInputStream(outputFile))) {
+ BuildEvent buildEvent;
+ while ((buildEvent = BuildEvent.parseDelimitedFrom(inputStream)) != null) {
+ BuildEventId buildEventId = buildEvent.getId();
+ // Note: This doesn't actually work. BEP does not issue these for actions
+ // that don't execute during the build, so we can't find the files
+ // for a no-op build the way we can for --experimental_show_artifacts
+ if (buildEventId.getIdCase() == IdCase.ACTION_COMPLETED) {
+ String output = buildEventId.getActionCompleted().getPrimaryOutput();
+ if (fileFilter.test(output)) {
+ result.add(new File(output));
+ }
+ }
+ }
+ } catch (IOException e) {
+ logger.error(e);
+ return ImmutableList.of();
+ }
+ if (!outputFile.delete()) {
+ logger.warn("Could not delete BEP output file: " + outputFile);
+ }
+ return result.build();
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperStderr.java b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperStderr.java
new file mode 100644
index 0000000..ef34dd6
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperStderr.java
@@ -0,0 +1,58 @@
+/*
+ * 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.command.buildresult;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream.LineProcessor;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import java.io.File;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.function.Predicate;
+
+class BuildResultHelperStderr implements BuildResultHelper {
+ private final ImmutableList.Builder<File> buildArtifacts = ImmutableList.builder();
+ private final ExperimentalShowArtifactsLineProcessor experimentalShowArtifactsLineProcessor;
+ private ImmutableList<File> result;
+
+ BuildResultHelperStderr(Predicate<String> fileFilter) {
+ experimentalShowArtifactsLineProcessor =
+ new ExperimentalShowArtifactsLineProcessor(buildArtifacts, fileFilter);
+ }
+
+ @Override
+ public List<String> getBuildFlags() {
+ return ImmutableList.of(BlazeFlags.EXPERIMENTAL_SHOW_ARTIFACTS);
+ }
+
+ @Override
+ public OutputStream stderr(LineProcessor... lineProcessors) {
+ return LineProcessingOutputStream.of(
+ ImmutableList.<LineProcessor>builder()
+ .add(experimentalShowArtifactsLineProcessor)
+ .add(lineProcessors)
+ .build());
+ }
+
+ @Override
+ public ImmutableList<File> getBuildArtifacts() {
+ if (result == null) {
+ result = buildArtifacts.build();
+ }
+ return result;
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/command/buildresult/ExperimentalShowArtifactsLineProcessor.java b/base/src/com/google/idea/blaze/base/command/buildresult/ExperimentalShowArtifactsLineProcessor.java
new file mode 100644
index 0000000..609867c
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/command/buildresult/ExperimentalShowArtifactsLineProcessor.java
@@ -0,0 +1,54 @@
+/*
+ * 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.command.buildresult;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
+import java.io.File;
+import java.util.function.Predicate;
+import org.jetbrains.annotations.NotNull;
+
+/** Collects the output of --experimental_show_artifacts */
+class ExperimentalShowArtifactsLineProcessor implements LineProcessingOutputStream.LineProcessor {
+ private static final String OUTPUT_START = "Build artifacts:";
+ private static final String OUTPUT_MARKER = ">>>";
+
+ private final ImmutableList.Builder<File> fileList;
+ private final Predicate<String> filter;
+ private boolean afterBuildResult = false;
+
+ ExperimentalShowArtifactsLineProcessor(
+ ImmutableList.Builder<File> fileList, Predicate<String> filter) {
+ this.fileList = fileList;
+ this.filter = filter;
+ }
+
+ @Override
+ public boolean processLine(@NotNull String line) {
+ if (!afterBuildResult) {
+ afterBuildResult = line.equals(OUTPUT_START);
+ return !afterBuildResult;
+ }
+ if (!line.startsWith(OUTPUT_MARKER)) {
+ return true;
+ }
+ 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..bf9d694 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
@@ -15,17 +15,17 @@
*/
package com.google.idea.blaze.base.command.info;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
-import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
-import com.intellij.openapi.components.ServiceManager;
-import java.util.List;
-import javax.annotation.Nullable;
+import com.intellij.openapi.diagnostic.Logger;
+import java.io.File;
+import java.io.Serializable;
-/** Runs the blaze info command. The results may be cached in the workspace. */
-public abstract class BlazeInfo {
+/** The data output by blaze info. */
+public class BlazeInfo implements Serializable {
+ public static final long serialVersionUID = 2L;
public static final String EXECUTION_ROOT_KEY = "execution_root";
public static final String PACKAGE_PATH_KEY = "package_path";
public static final String BUILD_LANGUAGE = "build-language";
@@ -34,6 +34,8 @@
public static final String COMMAND_LOG = "command_log";
public static final String RELEASE = "release";
+ private static final Logger logger = Logger.getInstance(BlazeInfo.class);
+
public static String blazeBinKey(BuildSystem buildSystem) {
switch (buildSystem) {
case Blaze:
@@ -67,46 +69,74 @@
}
}
- public static BlazeInfo getInstance() {
- return ServiceManager.getService(BlazeInfo.class);
+ private final ImmutableMap<String, String> blazeInfoMap;
+
+ private final File executionRoot;
+ private final ExecutionRootPath blazeBinExecutionRootPath;
+ private final ExecutionRootPath blazeGenfilesExecutionRootPath;
+ private final File outputBase;
+
+ public BlazeInfo(BuildSystem buildSystem, ImmutableMap<String, String> blazeInfoMap) {
+ this.blazeInfoMap = blazeInfoMap;
+ this.executionRoot = new File(getOrThrow(blazeInfoMap, EXECUTION_ROOT_KEY).trim());
+ this.blazeBinExecutionRootPath =
+ ExecutionRootPath.createAncestorRelativePath(
+ executionRoot, new File(getOrThrow(blazeInfoMap, blazeBinKey(buildSystem))));
+ this.blazeGenfilesExecutionRootPath =
+ ExecutionRootPath.createAncestorRelativePath(
+ executionRoot, new File(getOrThrow(blazeInfoMap, blazeGenfilesKey(buildSystem))));
+ this.outputBase = new File(getOrThrow(blazeInfoMap, OUTPUT_BASE_KEY).trim());
+ logger.assertTrue(blazeBinExecutionRootPath != null);
+ logger.assertTrue(blazeGenfilesExecutionRootPath != null);
}
- /**
- * @param blazeFlags The blaze flags that will be passed to Blaze.
- * @param key The key passed to blaze info
- * @return The blaze info value associated with the specified key
- */
- public abstract ListenableFuture<String> runBlazeInfo(
- @Nullable BlazeContext context,
- BuildSystem buildSystem,
- WorkspaceRoot workspaceRoot,
- List<String> blazeFlags,
- String key);
+ private static String getOrThrow(ImmutableMap<String, String> map, String key) {
+ String value = map.get(key);
+ if (value == null) {
+ throw new RuntimeException(String.format("Could not locate %s in info map", key));
+ }
+ return value;
+ }
- /**
- * @param blazeFlags The blaze flags that will be passed to Blaze.
- * @param key The key passed to blaze info
- * @return The blaze info value associated with the specified key
- */
- public abstract ListenableFuture<byte[]> runBlazeInfoGetBytes(
- @Nullable BlazeContext context,
- BuildSystem buildSystem,
- WorkspaceRoot workspaceRoot,
- List<String> blazeFlags,
- String key);
+ public String get(String key) {
+ return blazeInfoMap.get(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)}.
- *
- * @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,
- WorkspaceRoot workspaceRoot,
- List<String> blazeFlags);
+ public File getExecutionRoot() {
+ return executionRoot;
+ }
+
+ public ExecutionRootPath getBlazeBinExecutionRootPath() {
+ return blazeBinExecutionRootPath;
+ }
+
+ public ExecutionRootPath getBlazeGenfilesExecutionRootPath() {
+ return blazeGenfilesExecutionRootPath;
+ }
+
+ public File getGenfilesDirectory() {
+ return blazeGenfilesExecutionRootPath.getFileRootedAt(getExecutionRoot());
+ }
+
+ public File getBlazeBinDirectory() {
+ return blazeBinExecutionRootPath.getFileRootedAt(getExecutionRoot());
+ }
+
+ public File getOutputBase() {
+ return outputBase;
+ }
+
+ /** Creates a mock blaze info with the minimum information required for syncing. */
+ @VisibleForTesting
+ public static BlazeInfo createMockBlazeInfo(
+ String outputBase, String executionRoot, String blazeBin, String blazeGenFiles) {
+ BuildSystem buildSystem = BuildSystem.Bazel;
+ ImmutableMap.Builder<String, String> blazeInfoMap =
+ ImmutableMap.<String, String>builder()
+ .put(OUTPUT_BASE_KEY, outputBase)
+ .put(EXECUTION_ROOT_KEY, executionRoot)
+ .put(blazeBinKey(buildSystem), blazeBin)
+ .put(blazeGenfilesKey(buildSystem), blazeGenFiles);
+ return new BlazeInfo(buildSystem, blazeInfoMap.build());
+ }
}
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/BlazeInfoRunner.java b/base/src/com/google/idea/blaze/base/command/info/BlazeInfoRunner.java
new file mode 100644
index 0000000..fb29f7d
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/command/info/BlazeInfoRunner.java
@@ -0,0 +1,69 @@
+/*
+ * 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.command.info;
+
+import com.google.common.util.concurrent.ListenableFuture;
+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.components.ServiceManager;
+import java.util.List;
+
+/** Runs the blaze info command. The results may be cached in the workspace. */
+public abstract class BlazeInfoRunner {
+
+ public static BlazeInfoRunner getInstance() {
+ return ServiceManager.getService(BlazeInfoRunner.class);
+ }
+
+ /**
+ * @param blazeFlags The blaze flags that will be passed to Blaze.
+ * @param key The key passed to blaze info
+ * @return The blaze info value associated with the specified key
+ */
+ public abstract ListenableFuture<String> runBlazeInfo(
+ BlazeContext context,
+ String binaryPath,
+ WorkspaceRoot workspaceRoot,
+ List<String> blazeFlags,
+ String key);
+
+ /**
+ * @param blazeFlags The blaze flags that will be passed to Blaze.
+ * @param key The key passed to blaze info
+ * @return The blaze info value associated with the specified key
+ */
+ public abstract ListenableFuture<byte[]> runBlazeInfoGetBytes(
+ 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.
+ *
+ * @param blazeFlags The blaze flags that will be passed to Blaze.
+ * @return The blaze info data fields.
+ */
+ public abstract ListenableFuture<BlazeInfo> runBlazeInfo(
+ BlazeContext context,
+ BuildSystem buildSystem,
+ String binaryPath,
+ WorkspaceRoot workspaceRoot,
+ List<String> blazeFlags);
+}
diff --git a/base/src/com/google/idea/blaze/base/command/info/BlazeInfoImpl.java b/base/src/com/google/idea/blaze/base/command/info/BlazeInfoRunnerImpl.java
similarity index 74%
rename from base/src/com/google/idea/blaze/base/command/info/BlazeInfoImpl.java
rename to base/src/com/google/idea/blaze/base/command/info/BlazeInfoRunnerImpl.java
index 4b9fe6c..892da90 100644
--- a/base/src/com/google/idea/blaze/base/command/info/BlazeInfoImpl.java
+++ b/base/src/com/google/idea/blaze/base/command/info/BlazeInfoRunnerImpl.java
@@ -19,6 +19,8 @@
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;
@@ -29,77 +31,78 @@
import java.util.List;
import javax.annotation.Nullable;
-class BlazeInfoImpl extends BlazeInfo {
- private static final Logger logger = Logger.getInstance(BlazeInfoImpl.class);
+class BlazeInfoRunnerImpl extends BlazeInfoRunner {
+ private static final Logger logger = Logger.getInstance(BlazeInfoRunnerImpl.class);
@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,
+ public ListenableFuture<BlazeInfo> runBlazeInfo(
+ BlazeContext context,
BuildSystem buildSystem,
+ 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);
+ ImmutableMap<String, String> blazeInfoMap = parseBlazeInfoResult(blazeInfoString);
+ return new BlazeInfo(buildSystem, blazeInfoMap);
});
}
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..7317f31 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);
@@ -112,7 +112,7 @@
WorkspacePath newPackagePath = workspaceRoot.workspacePathFor(newPackageDirectory);
TargetName newTargetName = newRuleUI.getRuleName();
- Label newRule = new Label(newPackagePath, newTargetName);
+ Label newRule = Label.create(newPackagePath, newTargetName);
Kind ruleKind = newRuleUI.getSelectedRuleKind();
try {
parentDirectory.checkCreateSubdirectory(newPackageName);
diff --git a/base/src/com/google/idea/blaze/base/ide/NewBlazeRuleDialog.java b/base/src/com/google/idea/blaze/base/ide/NewBlazeRuleDialog.java
index d77e25c..ae43540 100644
--- a/base/src/com/google/idea/blaze/base/ide/NewBlazeRuleDialog.java
+++ b/base/src/com/google/idea/blaze/base/ide/NewBlazeRuleDialog.java
@@ -24,7 +24,6 @@
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.ui.UiUtil;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.ValidationInfo;
@@ -37,8 +36,6 @@
import javax.swing.JPanel;
class NewBlazeRuleDialog extends DialogWrapper {
- private static final Logger logger = Logger.getInstance(NewBlazeRuleDialog.class);
-
private static final int UI_INDENT = 0;
private static final int TEXT_BOX_WIDTH = 40;
@@ -94,7 +91,7 @@
WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
WorkspacePath workspacePath =
workspaceRoot.workspacePathFor(new File(buildFile.getParent().getPath()));
- Label newRule = new Label(workspacePath, targetName);
+ Label newRule = Label.create(workspacePath, targetName);
BuildFileModifier buildFileModifier = BuildFileModifier.getInstance();
boolean success = buildFileModifier.addRule(project, context, newRule, ruleKind);
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/ide/OpenBlazeWorkspaceFileAction.java b/base/src/com/google/idea/blaze/base/ide/OpenBlazeWorkspaceFileAction.java
new file mode 100644
index 0000000..68976c8
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/ide/OpenBlazeWorkspaceFileAction.java
@@ -0,0 +1,108 @@
+/*
+ * 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.ide;
+
+import com.google.idea.blaze.base.actions.BlazeProjectAction;
+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.WorkspacePathResolver;
+import com.google.idea.blaze.base.ui.UiUtil;
+import com.google.idea.blaze.base.ui.WorkspaceFileTextField;
+import com.intellij.ide.actions.OpenFileAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.fileChooser.FileTextField;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.components.JBLabel;
+import java.awt.GridBagLayout;
+import javax.annotation.Nullable;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+
+final class OpenBlazeWorkspaceFileAction extends BlazeProjectAction {
+
+ @Override
+ protected void actionPerformedInBlazeProject(Project project, AnActionEvent e) {
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
+ if (blazeProjectData == null) {
+ return;
+ }
+ new OpenBlazeWorkspaceFileActionDialog(project, blazeProjectData.workspacePathResolver).show();
+ }
+
+ private static class OpenBlazeWorkspaceFileActionDialog extends DialogWrapper {
+
+ static final int PATH_FIELD_WIDTH = 40;
+ final Project project;
+
+ final JPanel component;
+ final FileTextField fileTextField;
+
+ OpenBlazeWorkspaceFileActionDialog(
+ Project project, WorkspacePathResolver workspacePathResolver) {
+ super(project, /* canBeParent */ false, IdeModalityType.PROJECT);
+ this.project = project;
+
+ component = new JPanel(new GridBagLayout());
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileDescriptor();
+ fileTextField =
+ WorkspaceFileTextField.create(
+ workspacePathResolver, descriptor, PATH_FIELD_WIDTH, myDisposable);
+
+ component.add(new JBLabel("Path:"));
+ component.add(fileTextField.getField(), UiUtil.getFillLineConstraints(0));
+
+ UiUtil.fillBottom(component);
+ init();
+ }
+
+ @Nullable
+ @Override
+ protected JComponent createCenterPanel() {
+ return component;
+ }
+
+ @Nullable
+ @Override
+ public JComponent getPreferredFocusedComponent() {
+ return fileTextField.getField();
+ }
+
+ @Nullable
+ @Override
+ protected ValidationInfo doValidate() {
+ VirtualFile selectedFile = fileTextField.getSelectedFile();
+ if (selectedFile == null || !selectedFile.exists()) {
+ return new ValidationInfo("File does not exist", fileTextField.getField());
+ } else if (selectedFile.isDirectory()) {
+ return new ValidationInfo("Directories can not be opened", fileTextField.getField());
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ protected void doOKAction() {
+ OpenFileAction.openFile(fileTextField.getSelectedFile(), project);
+ super.doOKAction();
+ }
+ }
+}
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/run/testlogs/CompletedTestTarget.java b/base/src/com/google/idea/blaze/base/ideinfo/AndroidSdkIdeInfo.java
similarity index 60%
rename from base/src/com/google/idea/blaze/base/run/testlogs/CompletedTestTarget.java
rename to base/src/com/google/idea/blaze/base/ideinfo/AndroidSdkIdeInfo.java
index bf0b33b..1a07184 100644
--- a/base/src/com/google/idea/blaze/base/run/testlogs/CompletedTestTarget.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/AndroidSdkIdeInfo.java
@@ -13,19 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.google.idea.blaze.base.run.testlogs;
+package com.google.idea.blaze.base.ideinfo;
-import com.google.idea.blaze.base.model.primitives.Label;
-import java.io.File;
+import java.io.Serializable;
-/** Information relating to a completed test target. */
-public class CompletedTestTarget {
+/** android_sdk ide info */
+public class AndroidSdkIdeInfo implements Serializable {
+ private static final long serialVersionUID = 1L;
- public final File testResultXml;
- public final Label label;
+ public final ArtifactLocation androidJar;
- public CompletedTestTarget(File testResultXml, Label label) {
- this.testResultXml = testResultXml;
- this.label = label;
+ public AndroidSdkIdeInfo(ArtifactLocation androidJar) {
+ this.androidJar = androidJar;
}
}
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/ArtifactLocation.java b/base/src/com/google/idea/blaze/base/ideinfo/ArtifactLocation.java
index a23ab9c..72dc07c 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/ArtifactLocation.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/ArtifactLocation.java
@@ -22,9 +22,9 @@
/** Represents a blaze-produced artifact. */
public final class ArtifactLocation implements Serializable, Comparable<ArtifactLocation> {
- private static final long serialVersionUID = 4L;
+ private static final long serialVersionUID = 5L;
- public final String rootExecutionPathFragment;
+ private final String rootExecutionPathFragment;
public final String relativePath;
public final boolean isSource;
public final boolean isExternal;
@@ -37,7 +37,10 @@
this.isExternal = isExternal;
}
- /** Gets the path relative to the root path. */
+ /**
+ * The root-relative path. For external workspace artifacts, this is relative to the external
+ * workspace root.
+ */
public String getRelativePath() {
return relativePath;
}
@@ -50,10 +53,7 @@
return !isSource;
}
- /**
- * Returns rootExecutionPathFragment + relativePath. For source artifacts, this is simply
- * relativePath
- */
+ /** For main-workspace source artifacts, this is simply the workspace-relative path. */
public String getExecutionRootRelativePath() {
return Paths.get(rootExecutionPathFragment, relativePath).toString();
}
@@ -124,8 +124,8 @@
return ComparisonChain.start()
.compare(rootExecutionPathFragment, o.rootExecutionPathFragment)
.compare(relativePath, o.relativePath)
- .compare(isSource, o.isSource)
- .compare(isExternal, o.isExternal)
+ .compareFalseFirst(isSource, o.isSource)
+ .compareFalseFirst(isExternal, o.isExternal)
.result();
}
}
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/CIdeInfo.java b/base/src/com/google/idea/blaze/base/ideinfo/CIdeInfo.java
index de80f8c..215033d 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/CIdeInfo.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/CIdeInfo.java
@@ -21,10 +21,12 @@
/** Sister class to {@link JavaIdeInfo} */
public class CIdeInfo implements Serializable {
- private static final long serialVersionUID = 6L;
+ private static final long serialVersionUID = 7L;
public final ImmutableList<ArtifactLocation> sources;
+ public final ImmutableList<String> localDefines;
+ public final ImmutableList<ExecutionRootPath> localIncludeDirectories;
// From the cpp compilation context provider.
// These should all be for the entire transitive closure.
public final ImmutableList<ExecutionRootPath> transitiveIncludeDirectories;
@@ -34,11 +36,15 @@
public CIdeInfo(
ImmutableList<ArtifactLocation> sources,
+ ImmutableList<String> localDefines,
+ ImmutableList<ExecutionRootPath> localIncludeDirectories,
ImmutableList<ExecutionRootPath> transitiveIncludeDirectories,
ImmutableList<ExecutionRootPath> transitiveQuoteIncludeDirectories,
ImmutableList<String> transitiveDefines,
ImmutableList<ExecutionRootPath> transitiveSystemIncludeDirectories) {
this.sources = sources;
+ this.localDefines = localDefines;
+ this.localIncludeDirectories = localIncludeDirectories;
this.transitiveIncludeDirectories = transitiveIncludeDirectories;
this.transitiveQuoteIncludeDirectories = transitiveQuoteIncludeDirectories;
this.transitiveDefines = transitiveDefines;
@@ -53,6 +59,9 @@
public static class Builder {
private final ImmutableList.Builder<ArtifactLocation> sources = ImmutableList.builder();
+ private final ImmutableList.Builder<String> localDefines = ImmutableList.builder();
+ private final ImmutableList.Builder<ExecutionRootPath> localIncludeDirectories =
+ ImmutableList.builder();
private final ImmutableList.Builder<ExecutionRootPath> transitiveIncludeDirectories =
ImmutableList.builder();
private final ImmutableList.Builder<ExecutionRootPath> transitiveQuoteIncludeDirectories =
@@ -66,6 +75,16 @@
return this;
}
+ public Builder addLocalDefines(Iterable<String> localDefines) {
+ this.localDefines.addAll(localDefines);
+ return this;
+ }
+
+ public Builder addLocalIncludeDirectories(Iterable<ExecutionRootPath> localIncludeDirectories) {
+ this.localIncludeDirectories.addAll(localIncludeDirectories);
+ return this;
+ }
+
public Builder addTransitiveIncludeDirectories(
Iterable<ExecutionRootPath> transitiveIncludeDirectories) {
this.transitiveIncludeDirectories.addAll(transitiveIncludeDirectories);
@@ -92,6 +111,8 @@
public CIdeInfo build() {
return new CIdeInfo(
sources.build(),
+ localDefines.build(),
+ localIncludeDirectories.build(),
transitiveIncludeDirectories.build(),
transitiveQuoteIncludeDirectories.build(),
transitiveDefines.build(),
@@ -106,6 +127,12 @@
+ " sources="
+ sources
+ "\n"
+ + " localDefines="
+ + localDefines
+ + "\n"
+ + " localIncludeDirectories="
+ + localIncludeDirectories
+ + "\n"
+ " transitiveIncludeDirectories="
+ transitiveIncludeDirectories
+ "\n"
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/CToolchainIdeInfo.java b/base/src/com/google/idea/blaze/base/ideinfo/CToolchainIdeInfo.java
index f1c0174..5224256 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/CToolchainIdeInfo.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/CToolchainIdeInfo.java
@@ -20,7 +20,7 @@
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import java.io.Serializable;
-/** Sister class to {@link JavaIdeInfo} */
+/** Represents a cc_toolchain */
public class CToolchainIdeInfo implements Serializable {
private static final long serialVersionUID = 3L;
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/IntellijPluginDeployInfo.java b/base/src/com/google/idea/blaze/base/ideinfo/IntellijPluginDeployInfo.java
deleted file mode 100644
index 426fa6b..0000000
--- a/base/src/com/google/idea/blaze/base/ideinfo/IntellijPluginDeployInfo.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.ideinfo;
-
-import com.google.common.collect.ImmutableList;
-import java.io.Serializable;
-import javax.annotation.concurrent.Immutable;
-
-/** A special rule representing the files that need to be deployed for an IntelliJ plugin */
-@Immutable
-public class IntellijPluginDeployInfo implements Serializable {
- private static final long serialVersionUID = 1L;
-
- /** A single file for deployment */
- @Immutable
- public static class IntellijPluginDeployFile implements Serializable {
- private static final long serialVersionUID = 1L;
-
- /** The source file to deploy. */
- public final ArtifactLocation src;
- /** A plugins-directory relative location to deploy to. */
- public final String deployLocation;
-
- public IntellijPluginDeployFile(ArtifactLocation src, String deployLocation) {
- this.src = src;
- this.deployLocation = deployLocation;
- }
- }
-
- public final ImmutableList<IntellijPluginDeployFile> deployFiles;
-
- public IntellijPluginDeployInfo(ImmutableList<IntellijPluginDeployFile> deployFiles) {
- this.deployFiles = deployFiles;
- }
-}
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/TargetIdeInfo.java b/base/src/com/google/idea/blaze/base/ideinfo/TargetIdeInfo.java
index 34f2bc2..ecd44c5 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/TargetIdeInfo.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/TargetIdeInfo.java
@@ -27,7 +27,7 @@
/** Simple implementation of TargetIdeInfo. */
public final class TargetIdeInfo implements Serializable {
- private static final long serialVersionUID = 15L;
+ private static final long serialVersionUID = 17L;
public final TargetKey key;
public final Kind kind;
@@ -39,11 +39,11 @@
@Nullable public final CToolchainIdeInfo cToolchainIdeInfo;
@Nullable public final JavaIdeInfo javaIdeInfo;
@Nullable public final AndroidIdeInfo androidIdeInfo;
+ @Nullable public final AndroidSdkIdeInfo androidSdkIdeInfo;
@Nullable public final PyIdeInfo pyIdeInfo;
@Nullable public final TestIdeInfo testIdeInfo;
@Nullable public final ProtoLibraryLegacyInfo protoLibraryLegacyInfo;
@Nullable public final JavaToolchainIdeInfo javaToolchainIdeInfo;
- @Nullable public final IntellijPluginDeployInfo intellijPluginDeployInfo;
public TargetIdeInfo(
TargetKey key,
@@ -56,11 +56,11 @@
@Nullable CToolchainIdeInfo cToolchainIdeInfo,
@Nullable JavaIdeInfo javaIdeInfo,
@Nullable AndroidIdeInfo androidIdeInfo,
+ @Nullable AndroidSdkIdeInfo androidSdkIdeInfo,
@Nullable PyIdeInfo pyIdeInfo,
@Nullable TestIdeInfo testIdeInfo,
@Nullable ProtoLibraryLegacyInfo protoLibraryLegacyInfo,
- @Nullable JavaToolchainIdeInfo javaToolchainIdeInfo,
- @Nullable IntellijPluginDeployInfo intellijPluginDeployInfo) {
+ @Nullable JavaToolchainIdeInfo javaToolchainIdeInfo) {
this.key = key;
this.kind = kind;
this.buildFile = buildFile;
@@ -71,11 +71,11 @@
this.cToolchainIdeInfo = cToolchainIdeInfo;
this.javaIdeInfo = javaIdeInfo;
this.androidIdeInfo = androidIdeInfo;
+ this.androidSdkIdeInfo = androidSdkIdeInfo;
this.pyIdeInfo = pyIdeInfo;
this.testIdeInfo = testIdeInfo;
this.protoLibraryLegacyInfo = protoLibraryLegacyInfo;
this.javaToolchainIdeInfo = javaToolchainIdeInfo;
- this.intellijPluginDeployInfo = intellijPluginDeployInfo;
}
@Override
@@ -89,7 +89,7 @@
}
/** Returns whether this rule is one of the kinds. */
- public boolean kindIsOneOf(List<Kind> kinds) {
+ public boolean kindIsOneOf(Collection<Kind> kinds) {
if (kind != null) {
return kind.isOneOf(kinds);
}
@@ -122,7 +122,7 @@
private JavaToolchainIdeInfo javaToolchainIdeInfo;
public Builder setLabel(String label) {
- return setLabel(new Label(label));
+ return setLabel(Label.create(label));
}
public Builder setLabel(Label label) {
@@ -212,7 +212,7 @@
}
public Builder addDependency(String s) {
- return addDependency(new Label(s));
+ return addDependency(Label.create(s));
}
public Builder addDependency(Label label) {
@@ -222,7 +222,7 @@
}
public Builder addRuntimeDep(String s) {
- return addRuntimeDep(new Label(s));
+ return addRuntimeDep(Label.create(s));
}
public Builder addRuntimeDep(Label label) {
@@ -243,11 +243,11 @@
cToolchainIdeInfo,
javaIdeInfo,
androidIdeInfo,
+ null,
pyIdeInfo,
testIdeInfo,
protoLibraryLegacyInfo,
- javaToolchainIdeInfo,
- null);
+ javaToolchainIdeInfo);
}
}
}
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/issueparser/BlazeIssueParser.java b/base/src/com/google/idea/blaze/base/issueparser/BlazeIssueParser.java
index 2ebd868..55755ec 100644
--- a/base/src/com/google/idea/blaze/base/issueparser/BlazeIssueParser.java
+++ b/base/src/com/google/idea/blaze/base/issueparser/BlazeIssueParser.java
@@ -36,11 +36,11 @@
import java.util.regex.Pattern;
import javax.annotation.Nullable;
-
/** Parses blaze output for compile errors. */
public class BlazeIssueParser {
- private static class ParseResult {
+ /** Result from parsing the current line */
+ public static class ParseResult {
public static final ParseResult NEEDS_MORE_INPUT = new ParseResult(true, null);
@@ -117,9 +117,9 @@
/** Returns the file referenced by the target */
@Nullable
- public static File fileFromTarget(WorkspaceRoot workspaceRoot, String targetString) {
+ private static File fileFromTarget(WorkspaceRoot workspaceRoot, String targetString) {
Label label = Label.createIfValid(targetString);
- if (label == null) {
+ if (label == null || label.isExternal()) {
return null;
}
try {
@@ -132,7 +132,10 @@
}
/** Falls back to returning -1 if no integer can be parsed. */
- public static int parseOptionalInt(String intString) {
+ public static int parseOptionalInt(@Nullable String intString) {
+ if (intString == null) {
+ return -1;
+ }
try {
return Integer.parseInt(intString);
} catch (NumberFormatException e) {
@@ -215,6 +218,22 @@
}
}
+ static class SkylarkErrorParser extends SingleLineParser {
+ SkylarkErrorParser() {
+ super("^ERROR: (/.*?\\.bzl):([0-9]+):([0-9]+): (.*)$");
+ }
+
+ @Override
+ protected IssueOutput createIssue(Matcher matcher) {
+ File file = fileFromAbsolutePath(matcher.group(1));
+ return IssueOutput.error(matcher.group(4))
+ .inFile(file)
+ .onLine(Integer.parseInt(matcher.group(2)))
+ .inColumn(parseOptionalInt(matcher.group(3)))
+ .build();
+ }
+ }
+
static class LinelessBuildParser extends SingleLineParser {
LinelessBuildParser() {
super("^ERROR: (.*?):char offsets [0-9]+--[0-9]+: (.*)$");
diff --git a/base/src/com/google/idea/blaze/base/issueparser/IssueOutputLineProcessor.java b/base/src/com/google/idea/blaze/base/issueparser/IssueOutputLineProcessor.java
index c3c5de2..a5588dc 100644
--- a/base/src/com/google/idea/blaze/base/issueparser/IssueOutputLineProcessor.java
+++ b/base/src/com/google/idea/blaze/base/issueparser/IssueOutputLineProcessor.java
@@ -49,6 +49,7 @@
new BlazeIssueParser.CompileParser(workspaceRoot),
new BlazeIssueParser.TracebackParser(),
new BlazeIssueParser.BuildParser(),
+ new BlazeIssueParser.SkylarkErrorParser(),
new BlazeIssueParser.LinelessBuildParser(),
new BlazeIssueParser.ProjectViewLabelParser(projectViewSet),
new BlazeIssueParser.InvalidTargetProjectViewPackageParser(
diff --git a/base/src/com/google/idea/blaze/base/lang/AdditionalLanguagesHelper.java b/base/src/com/google/idea/blaze/base/lang/AdditionalLanguagesHelper.java
index 384e35b..a55996c 100644
--- a/base/src/com/google/idea/blaze/base/lang/AdditionalLanguagesHelper.java
+++ b/base/src/com/google/idea/blaze/base/lang/AdditionalLanguagesHelper.java
@@ -15,6 +15,7 @@
*/
package com.google.idea.blaze.base.lang;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
@@ -35,6 +36,7 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
+import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
@@ -111,12 +113,15 @@
panel.setText(message);
panel.createActionLabel(
String.format("Enable %s support", langName),
- () -> enableLanguageSupport(project, language));
+ () -> {
+ enableLanguageSupport(project, ImmutableList.of(language));
+ suppressNotifications(language);
+ });
panel.createActionLabel("Don't show again", () -> suppressNotifications(language));
return panel;
}
- private void enableLanguageSupport(Project project, LanguageClass language) {
+ public static void enableLanguageSupport(Project project, List<LanguageClass> languages) {
ProjectViewEdit edit =
ProjectViewEdit.editLocalProjectView(
project,
@@ -126,7 +131,7 @@
builder.replace(
existingSection,
ListSection.update(AdditionalLanguagesSection.KEY, existingSection)
- .add(language));
+ .addAll(languages));
return true;
});
if (edit == null) {
@@ -137,8 +142,6 @@
}
edit.apply();
- suppressNotifications(language);
-
BlazeSyncManager.getInstance(project)
.requestProjectSync(
new BlazeSyncParams.Builder("Sync", BlazeSyncParams.SyncMode.INCREMENTAL)
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/BuildLookupElement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/BuildLookupElement.java
index cc05ea4..cd01e0d 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/BuildLookupElement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/BuildLookupElement.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.lang.buildfile.completion;
import com.google.idea.blaze.base.lang.buildfile.references.QuoteType;
+import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementPresentation;
@@ -42,9 +43,15 @@
this.wrapWithQuotes = quoteWrapping != QuoteType.NoQuotes;
}
+ private static boolean insertClosingQuotes() {
+ return CodeInsightSettings.getInstance().AUTOINSERT_PAIR_QUOTE;
+ }
+
@Override
public String getLookupString() {
- return quoteWrapping.wrap(baseName);
+ return insertClosingQuotes()
+ ? quoteWrapping.wrap(baseName)
+ : quoteWrapping.quoteString + baseName;
}
@Nullable
@@ -75,19 +82,17 @@
/**
* If we're wrapping with quotes, handle the (very common) case where we have a closing quote
* after the caret -- we want to remove this quote.
- *
- * @param context
*/
@Override
public void handleInsert(InsertionContext context) {
- if (!wrapWithQuotes) {
+ if (!wrapWithQuotes || !insertClosingQuotes()) {
super.handleInsert(context);
return;
}
Document document = context.getDocument();
context.commitDocument();
PsiElement suffix = context.getFile().findElementAt(context.getTailOffset());
- if (suffix.getText().startsWith(quoteWrapping.quoteString)) {
+ if (suffix != null && suffix.getText().startsWith(quoteWrapping.quoteString)) {
int offset = suffix.getTextOffset();
document.deleteString(offset, offset + 1);
context.commitDocument();
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionAttributeCompletionContributor.java b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionAttributeCompletionContributor.java
index 1b16003..1d84632 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionAttributeCompletionContributor.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionAttributeCompletionContributor.java
@@ -96,7 +96,7 @@
@Nullable
private static String getEnclosingFuncallName(PsiElement element) {
- FuncallExpression funcall = PsiUtils.getParentOfType(element, FuncallExpression.class);
+ FuncallExpression funcall = PsiUtils.getParentOfType(element, FuncallExpression.class, true);
return funcall != null ? funcall.getFunctionName() : null;
}
}
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/FilePathLookupElement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/FilePathLookupElement.java
index 61d40e9..0a5a958 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/FilePathLookupElement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/FilePathLookupElement.java
@@ -20,7 +20,7 @@
import javax.annotation.Nullable;
import javax.swing.Icon;
-/** Code completion support for package paths. */
+/** Code completion support for file paths within BUILD file labels. */
public class FilePathLookupElement extends BuildLookupElement {
private final String itemText;
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/completion/LabelRuleLookupElement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/LabelRuleLookupElement.java
index dc7dc46..0b9af98 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/completion/LabelRuleLookupElement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/completion/LabelRuleLookupElement.java
@@ -16,8 +16,6 @@
package com.google.idea.blaze.base.lang.buildfile.completion;
import com.google.common.collect.Lists;
-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.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
import com.google.idea.blaze.base.lang.buildfile.references.LabelUtils;
@@ -45,9 +43,6 @@
String ruleFragment = LabelUtils.getRuleComponent(originalString);
List<BuildLookupElement> lookups = Lists.newArrayList();
- // TODO: Handle rules generated via functions? (e.g. via blaze sync)
- BuildLanguageSpec spec =
- BuildLanguageSpecProvider.getInstance().getLanguageSpec(file.getProject());
for (FuncallExpression target : file.findChildrenByClass(FuncallExpression.class)) {
String targetName = target.getName();
if (targetName == null
@@ -56,7 +51,7 @@
continue;
}
String ruleType = target.getFunctionName();
- if (ruleType == null || (spec != null && !spec.hasRule(ruleType))) {
+ if (ruleType == null) {
continue;
}
lookups.add(
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/documentation/BuildDocumentationProvider.java b/base/src/com/google/idea/blaze/base/lang/buildfile/documentation/BuildDocumentationProvider.java
index 8c96eec..6f1b195 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/documentation/BuildDocumentationProvider.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/documentation/BuildDocumentationProvider.java
@@ -24,6 +24,7 @@
import com.google.idea.blaze.base.lang.buildfile.psi.FunctionStatement;
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.model.primitives.Label;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.codeInsight.documentation.DocumentationManagerProtocol;
import com.intellij.lang.documentation.AbstractDocumentationProvider;
@@ -77,11 +78,8 @@
return;
}
BuildFile buildFile = (BuildFile) file;
- String name = buildFile.getBuildLabel();
- if (name == null) {
- // fall back to qualitative description
- name = buildFile.getPresentableText();
- }
+ Label label = buildFile.getBuildLabel();
+ String name = label != null ? label.toString() : buildFile.getPresentableText();
if (linkToFile) {
builder
.append("<a href=\"")
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/findusages/BuildReadWriteAccessDetector.java b/base/src/com/google/idea/blaze/base/lang/buildfile/findusages/BuildReadWriteAccessDetector.java
index 8f01178..c28b741 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/findusages/BuildReadWriteAccessDetector.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/findusages/BuildReadWriteAccessDetector.java
@@ -46,7 +46,7 @@
return Access.Write;
}
if (expression instanceof ReferenceExpression) {
- if (PsiUtils.getParentOfType(expression, AugmentedAssignmentStatement.class) != null) {
+ if (PsiUtils.getParentOfType(expression, AugmentedAssignmentStatement.class, true) != null) {
return Access.ReadWrite;
}
}
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/globbing/UnixGlob.java b/base/src/com/google/idea/blaze/base/lang/buildfile/globbing/UnixGlob.java
index b7a44c4..ab7ede4 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/globbing/UnixGlob.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/globbing/UnixGlob.java
@@ -15,7 +15,6 @@
*/
package com.google.idea.blaze.base.lang.buildfile.globbing;
-import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Throwables;
import com.google.common.cache.Cache;
@@ -31,17 +30,14 @@
import com.google.common.util.concurrent.SettableFuture;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.lang.buildfile.validation.GlobPatternValidator;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
@@ -49,6 +45,7 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
import javax.annotation.Nullable;
/**
@@ -63,35 +60,16 @@
public final class UnixGlob {
private UnixGlob() {}
- private static List<File> globInternal(
+ private static Set<File> globInternal(
File base,
Collection<String> patterns,
- Collection<String> excludePatterns,
boolean excludeDirectories,
Predicate<File> dirPred,
ThreadPoolExecutor threadPool)
throws IOException, InterruptedException {
GlobVisitor visitor = (threadPool == null) ? new GlobVisitor() : new GlobVisitor(threadPool);
- return visitor.glob(base, patterns, excludePatterns, excludeDirectories, dirPred);
- }
-
- private static Future<List<File>> globAsyncInternal(
- File base,
- Collection<String> patterns,
- Collection<String> excludePatterns,
- boolean excludeDirectories,
- Predicate<File> dirPred,
- ThreadPoolExecutor threadPool) {
- Preconditions.checkNotNull(threadPool, "%s %s", base, patterns);
- try {
- return new GlobVisitor(threadPool)
- .globAsync(base, patterns, excludePatterns, excludeDirectories, dirPred);
- } catch (IOException e) {
- // We are evaluating asynchronously, so no exceptions should be thrown until the future is
- // retrieved.
- throw new IllegalStateException(e);
- }
+ return visitor.glob(base, patterns, excludeDirectories, dirPred);
}
/**
@@ -113,58 +91,13 @@
return list;
}
- private static boolean excludedOnMatch(
- File path, List<String[]> excludePatterns, int idx, Cache<String, Pattern> cache) {
- for (String[] excludePattern : excludePatterns) {
- String text = path.getName();
- if (idx == excludePattern.length && matches(excludePattern[idx - 1], text, cache)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns the exclude patterns in {@code excludePatterns} which could apply to the children of
- * {@code base}
- *
- * @param idx index into {@code excludePatterns} for the part of the pattern which might match
- * {@code base}
- */
- private static List<String[]> getRelevantExcludes(
- final File base,
- List<String[]> excludePatterns,
- final int idx,
- final Cache<String, Pattern> cache) {
-
- if (excludePatterns.isEmpty()) {
- return excludePatterns;
- }
- List<String[]> list = new ArrayList<>();
- for (String[] patterns : excludePatterns) {
- if (excludePatternMatches(patterns, idx, base, cache)) {
- list.add(patterns);
- }
- }
- return list;
- }
-
- /**
- * @param patterns a list of patterns
- * @param idx index into {@code patterns}
- */
- private static boolean excludePatternMatches(
- String[] patterns, int idx, File base, Cache<String, Pattern> cache) {
- if (idx == 0) {
- return true;
- }
- String text = base.getName();
- return patterns.length > idx && matches(patterns[idx - 1], text, cache);
- }
-
/** Calls {@link #matches(String, String, Cache) matches(pattern, str, null)} */
public static boolean matches(String pattern, String str) {
- return matches(pattern, str, null);
+ try {
+ return matches(pattern, str, null);
+ } catch (PatternSyntaxException e) {
+ return false;
+ }
}
/**
@@ -176,7 +109,7 @@
* @param patternCache a cache from patterns to compiled Pattern objects, or {@code null} to skip
* caching
*/
- public static boolean matches(String pattern, String str, Cache<String, Pattern> patternCache) {
+ private static boolean matches(String pattern, String str, Cache<String, Pattern> patternCache) {
if (pattern.length() == 0 || str.length() == 0) {
return false;
}
@@ -278,8 +211,8 @@
/** Builder class for UnixGlob. */
public static class Builder {
private File base;
- private List<String> patterns;
- private List<String> excludes;
+ private final List<String> patterns = new ArrayList<>();
+ private final List<String> excludes = new ArrayList<>();
private boolean excludeDirectories;
private Predicate<File> pathFilter;
private ThreadPoolExecutor threadPool;
@@ -287,8 +220,6 @@
/** Creates a glob builder with the given base path. */
public Builder(File base) {
this.base = base;
- this.patterns = Lists.newArrayList();
- this.excludes = Lists.newArrayList();
this.excludeDirectories = false;
this.pathFilter = file -> true;
}
@@ -374,37 +305,29 @@
* @throws InterruptedException if the thread is interrupted.
*/
public List<File> glob() throws IOException, InterruptedException {
- return globInternal(base, patterns, excludes, excludeDirectories, pathFilter, threadPool);
- }
-
- /**
- * Executes the glob asynchronously. {@link #setThreadPool} must have been called already with a
- * non-null argument.
- *
- * @param checkForInterrupt if the returned future may throw InterruptedException.
- */
- public Future<List<File>> globAsync() {
- return globAsyncInternal(
- base, patterns, excludes, excludeDirectories, pathFilter, threadPool);
+ Set<File> included = globInternal(base, patterns, excludeDirectories, pathFilter, threadPool);
+ Set<File> excluded = globInternal(base, excludes, excludeDirectories, pathFilter, threadPool);
+ included.removeAll(excluded);
+ return Ordering.<File>natural().immutableSortedCopy(included);
}
}
/** Adapts the result of the glob visitation as a Future. */
- private static class GlobFuture extends ForwardingListenableFuture<List<File>> {
+ private static class GlobFuture extends ForwardingListenableFuture<Set<File>> {
private final GlobVisitor visitor;
- private final SettableFuture<List<File>> delegate = SettableFuture.create();
+ private final SettableFuture<Set<File>> delegate = SettableFuture.create();
- public GlobFuture(GlobVisitor visitor) {
+ private GlobFuture(GlobVisitor visitor) {
this.visitor = visitor;
}
@Override
- public List<File> get() throws InterruptedException, ExecutionException {
+ public Set<File> get() throws InterruptedException, ExecutionException {
return super.get();
}
@Override
- protected ListenableFuture<List<File>> delegate() {
+ protected ListenableFuture<Set<File>> delegate() {
return delegate;
}
@@ -412,7 +335,7 @@
delegate.setException(exception);
}
- public void set(List<File> paths) {
+ public void set(Set<File> paths) {
delegate.set(paths);
}
@@ -423,7 +346,7 @@
return true;
}
- public void markCanceled() {
+ void markCanceled() {
super.cancel(true);
}
}
@@ -434,7 +357,7 @@
*/
private static final class GlobVisitor {
// These collections are used across workers and must therefore be thread-safe.
- private final Collection<File> results = Sets.newConcurrentHashSet();
+ private final Set<File> results = Sets.newConcurrentHashSet();
private final Cache<String, Pattern> cache =
CacheBuilder.newBuilder()
.build(
@@ -452,40 +375,34 @@
private final FileAttributeProvider fileAttributeProvider = FileAttributeProvider.getInstance();
private volatile boolean canceled = false;
- public GlobVisitor(ThreadPoolExecutor executor) {
+ private GlobVisitor(ThreadPoolExecutor executor) {
this.executor = executor;
this.result = new GlobFuture(this);
}
- public GlobVisitor() {
+ private GlobVisitor() {
this(null);
}
/**
* Performs wildcard globbing: returns the sorted list of filenames that match any of {@code
- * patterns} relative to {@code base}, but which do not match {@code excludePatterns}.
- * Directories are traversed if and only if they match {@code dirPred}. The predicate is also
- * called for the root of the traversal.
+ * patterns} relative to {@code base}. Directories are traversed if and only if they match
+ * {@code dirPred}. The predicate is also called for the root of the traversal.
*
* <p>Patterns may include "*" and "?", but not "[a-z]".
*
* <p><code>**</code> gets special treatment in include patterns. If it is used as a complete
* path segment it matches the filenames in subdirectories recursively.
*
- * @throws IllegalArgumentException if any glob or exclude pattern {@linkplain
- * #checkPatternForError(String) contains errors} or if any exclude pattern segment contains
- * <code>**</code> or if any include pattern segment contains <code>**</code> but not equal
- * to it.
+ * @throws IllegalArgumentException if any glob or exclude pattern contains errors, or if any
+ * exclude pattern segment contains <code>**</code> or if any include pattern segment
+ * contains <code>**</code> but not equal to it.
*/
- public List<File> glob(
- File base,
- Collection<String> patterns,
- Collection<String> excludePatterns,
- boolean excludeDirectories,
- Predicate<File> dirPred)
+ private Set<File> glob(
+ File base, Collection<String> patterns, boolean excludeDirectories, Predicate<File> dirPred)
throws IOException, InterruptedException {
try {
- return globAsync(base, patterns, excludePatterns, excludeDirectories, dirPred).get();
+ return globAsync(base, patterns, excludeDirectories, dirPred).get();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
Throwables.propagateIfPossible(cause, IOException.class);
@@ -493,40 +410,24 @@
}
}
- public Future<List<File>> globAsync(
- File base,
- Collection<String> patterns,
- Collection<String> excludePatterns,
- boolean excludeDirectories,
- Predicate<File> dirPred)
+ private Future<Set<File>> globAsync(
+ File base, Collection<String> patterns, boolean excludeDirectories, Predicate<File> dirPred)
throws IOException {
if (!fileAttributeProvider.exists(base) || patterns.isEmpty()) {
- return Futures.immediateFuture(Collections.emptyList());
+ return Futures.immediateFuture(Collections.emptySet());
}
boolean baseIsDirectory = fileAttributeProvider.isDirectory(base);
- List<String[]> splitPatterns = checkAndSplitPatterns(patterns);
- List<String[]> splitExcludes = checkAndSplitPatterns(excludePatterns);
-
// We do a dumb loop, even though it will likely duplicate work
// (e.g., readdir calls). In order to optimize, we would need
// to keep track of which patterns shared sub-patterns and which did not
// (for example consider the glob [*/*.java, sub/*.java, */*.txt]).
pendingOps.incrementAndGet();
try {
- for (String[] splitPattern : splitPatterns) {
+ for (String[] splitPattern : checkAndSplitPatterns(patterns)) {
queueGlob(
- base,
- baseIsDirectory,
- splitPattern,
- 0,
- excludeDirectories,
- splitExcludes,
- 0,
- results,
- cache,
- dirPred);
+ base, baseIsDirectory, splitPattern, 0, excludeDirectories, results, cache, dirPred);
}
} finally {
decrementAndCheckDone();
@@ -541,8 +442,6 @@
String[] patternParts,
int idx,
boolean excludeDirectories,
- List<String[]> excludePatterns,
- int excludeIdx,
Collection<File> results,
Cache<String, Pattern> cache,
Predicate<File> dirPred)
@@ -556,8 +455,6 @@
patternParts,
idx,
excludeDirectories,
- excludePatterns,
- excludeIdx,
results,
cache,
dirPred);
@@ -567,7 +464,7 @@
});
}
- protected void enqueue(final Runnable r) {
+ void enqueue(final Runnable r) {
pendingOps.incrementAndGet();
Runnable wrapped =
@@ -602,7 +499,7 @@
} else if (failure.get() != null) {
result.setException(failure.get());
} else {
- result.set(Ordering.<File>natural().immutableSortedCopy(results));
+ result.set(results);
}
}
}
@@ -621,8 +518,6 @@
String[] patternParts,
int idx,
boolean excludeDirectories,
- List<String[]> excludePatterns,
- int excludeIdx,
Collection<File> results,
Cache<String, Pattern> cache,
Predicate<File> dirPred)
@@ -633,8 +528,7 @@
}
if (idx == patternParts.length) { // Base case.
- if (!(excludeDirectories && baseIsDirectory)
- && !excludedOnMatch(base, excludePatterns, excludeIdx, cache)) {
+ if (!(excludeDirectories && baseIsDirectory)) {
results.add(base);
}
return;
@@ -645,8 +539,6 @@
return;
}
- List<String[]> relevantExcludes =
- getRelevantExcludes(base, excludePatterns, excludeIdx, cache);
final String pattern = patternParts[idx];
// ** is special: it can match nothing at all.
@@ -658,8 +550,6 @@
patternParts,
idx + 1,
excludeDirectories,
- excludePatterns,
- excludeIdx,
results,
cache,
dirPred);
@@ -675,16 +565,7 @@
}
queueGlob(
- child,
- childIsDir,
- patternParts,
- idx + 1,
- excludeDirectories,
- relevantExcludes,
- excludeIdx + 1,
- results,
- cache,
- dirPred);
+ child, childIsDir, patternParts, idx + 1, excludeDirectories, results, cache, dirPred);
return;
}
@@ -699,16 +580,7 @@
// Recurse without shifting the pattern.
if (childIsDir) {
queueGlob(
- child,
- childIsDir,
- patternParts,
- idx,
- excludeDirectories,
- relevantExcludes,
- excludeIdx + 1,
- results,
- cache,
- dirPred);
+ child, childIsDir, patternParts, idx, excludeDirectories, results, cache, dirPred);
}
}
if (matches(pattern, child.getName(), cache)) {
@@ -720,15 +592,12 @@
patternParts,
idx + 1,
excludeDirectories,
- relevantExcludes,
- excludeIdx + 1,
results,
cache,
dirPred);
} else {
// Instead of using an async call, just repeat the base case above.
- if (idx + 1 == patternParts.length
- && !excludedOnMatch(child, relevantExcludes, excludeIdx + 1, cache)) {
+ if (idx + 1 == patternParts.length) {
results.add(child);
}
}
@@ -738,16 +607,7 @@
@Nullable
private File[] getChildren(File file) {
- if (!ApplicationManager.getApplication().isUnitTestMode()) {
- return file.listFiles();
- }
- TempFileSystem fs = TempFileSystem.getInstance();
- VirtualFile vf = fs.findFileByIoFile(file);
- VirtualFile[] children = vf.getChildren();
- if (children == null) {
- return null;
- }
- return Arrays.stream(children).map(VirtualFile::getPath).map(File::new).toArray(File[]::new);
+ return FileAttributeProvider.getInstance().listFiles(file);
}
}
}
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..a73c0a4 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,9 @@
*/
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 +27,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().buildLanguageFileTypeMatchers())
+ .add()
+ .build();
+ consumer.consume(BuildFileType.INSTANCE, fileNameMatchers.toArray(new FileNameMatcher[0]));
}
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/Argument.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/Argument.java
index 67ff005..ecf79f8 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/Argument.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/Argument.java
@@ -107,13 +107,15 @@
}
}
+ /** Variable number of positional arguments: *args */
static class Star extends Argument {
public Star(ASTNode node) {
super(node);
}
}
- static class StarStar extends Argument {
+ /** Variable number of keyword arguments: **kwargs */
+ public static class StarStar extends Argument {
public StarStar(ASTNode node) {
super(node);
}
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/BuildElement.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildElement.java
index 35a67c5..7cfd64b 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildElement.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildElement.java
@@ -16,7 +16,6 @@
package com.google.idea.blaze.base.lang.buildfile.psi;
import com.google.idea.blaze.base.lang.buildfile.search.BlazePackage;
-import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.PsiElement;
import javax.annotation.Nullable;
@@ -41,8 +40,6 @@
@Nullable
<P extends PsiElement> P firstChildOfClass(Class<P> psiClass);
- WorkspacePath getWorkspacePath();
-
@Nullable
BlazePackage getBlazePackage();
}
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..700f4dc 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
@@ -16,7 +16,6 @@
package com.google.idea.blaze.base.lang.buildfile.psi;
import com.google.idea.blaze.base.lang.buildfile.search.BlazePackage;
-import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
@@ -82,13 +81,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
@@ -159,13 +159,6 @@
@Nullable
@Override
- public WorkspacePath getWorkspacePath() {
- BuildFile file = (BuildFile) getContainingFile();
- return file.getWorkspacePath();
- }
-
- @Nullable
- @Override
public BlazePackage getBlazePackage() {
PsiFile file = getContainingFile();
return file != null ? BlazePackage.getContainingPackage(file) : null;
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildFile.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildFile.java
index b9cc459..75c6417 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildFile.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/BuildFile.java
@@ -15,26 +15,22 @@
*/
package com.google.idea.blaze.base.lang.buildfile.psi;
-import com.google.common.collect.Lists;
import com.google.idea.blaze.base.lang.buildfile.language.BuildFileType;
-import com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager;
import com.google.idea.blaze.base.lang.buildfile.references.QuoteType;
import com.google.idea.blaze.base.lang.buildfile.search.BlazePackage;
-import com.google.idea.blaze.base.lang.buildfile.search.ResolveUtil;
-import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.sync.workspace.WorkspaceHelper;
import com.intellij.extapi.psi.PsiFileBase;
-import com.intellij.lang.ASTNode;
+import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
-import com.intellij.psi.tree.TokenSet;
import com.intellij.util.PathUtil;
import com.intellij.util.Processor;
import icons.BlazeIcons;
import java.io.File;
-import java.util.List;
import javax.annotation.Nullable;
import javax.swing.Icon;
@@ -44,24 +40,17 @@
/** The blaze file type */
public enum BlazeFileType {
SkylarkExtension,
- BuildPackage // "BUILD", plus hacks such as "BUILD.tools", "BUILD.bazel"
- }
-
- @Nullable
- public static WorkspacePath getWorkspacePath(Project project, String filePath) {
- return BuildReferenceManager.getInstance(project).getWorkspaceRelativePath(filePath);
+ BuildPackage, // "BUILD", "BUILD.bazel"
+ Workspace, // the top-level WORKSPACE file
}
public static String getBuildFileString(Project project, String filePath) {
- WorkspacePath workspacePath = getWorkspacePath(project, PathUtil.getParentPath(filePath));
- if (workspacePath == null) {
+ Label label = WorkspaceHelper.getBuildLabel(project, new File(filePath));
+ if (label == null) {
return "BUILD file: " + filePath;
}
- String fileName = PathUtil.getFileName(filePath);
- if (fileName.startsWith("BUILD")) {
- return "//" + workspacePath + "/" + fileName;
- }
- return "//" + workspacePath + ":" + fileName;
+ String labelString = label.toString();
+ return labelString.replace(":__pkg__", "/" + PathUtil.getFileName(filePath));
}
public BuildFile(FileViewProvider viewProvider) {
@@ -78,6 +67,9 @@
if (fileName.startsWith("BUILD")) {
return BlazeFileType.BuildPackage;
}
+ if (fileName.equals("WORKSPACE")) {
+ return BlazeFileType.Workspace;
+ }
return BlazeFileType.SkylarkExtension;
}
@@ -117,37 +109,19 @@
return new File(getFilePath());
}
- @Nullable
- @Override
- public WorkspacePath getWorkspacePath() {
- return getWorkspacePath(getProject(), getFilePath());
- }
-
/**
- * The workspace path of the containing blaze package (this is always the parent directory for
- * BUILD files, but may be a more distant ancestor for Skylark extensions)
+ * The label of the containing blaze package (this is always the parent directory for BUILD files,
+ * but may be a more distant ancestor for Skylark extensions)
*/
@Nullable
- public WorkspacePath getPackageWorkspacePath() {
+ public Label getPackageLabel() {
BlazePackage parentPackage = getBlazePackage();
- if (parentPackage == null) {
- return null;
- }
- String filePath = parentPackage.buildFile.getFilePath();
- return filePath != null
- ? getWorkspacePath(getProject(), PathUtil.getParentPath(filePath))
- : null;
- }
-
- @Nullable
- public String getWorkspaceRelativePackagePath() {
- WorkspacePath packagePath = getPackageWorkspacePath();
- return packagePath != null ? packagePath.relativePath() : null;
+ return parentPackage != null ? parentPackage.getPackageLabel() : null;
}
/** The path for this file, formatted as a BUILD label. */
@Nullable
- public String getBuildLabel() {
+ public Label getBuildLabel() {
BlazePackage containingPackage = getBlazePackage();
return containingPackage != null
? containingPackage.getBuildLabelForChild(getFilePath())
@@ -166,24 +140,6 @@
return null;
}
- /** .bzl files referenced in 'load' statements */
- @Nullable
- public String[] getImportedPaths() {
- ASTNode[] loadStatements =
- getNode().getChildren(TokenSet.create(BuildElementTypes.LOAD_STATEMENT));
- if (loadStatements.length == 0) {
- return null;
- }
- List<String> importedPaths = Lists.newArrayListWithCapacity(loadStatements.length);
- for (int i = 0; i < loadStatements.length; i++) {
- String path = ((LoadStatement) loadStatements[i].getPsi()).getImportedPath();
- if (path != null) {
- importedPaths.add(path);
- }
- }
- return importedPaths.toArray(new String[importedPaths.size()]);
- }
-
@Nullable
public FunctionStatement findDeclaredFunction(String name) {
for (FunctionStatement fn : getFunctionDeclarations()) {
@@ -195,11 +151,6 @@
}
@Nullable
- public TargetExpression findTopLevelVariable(String name) {
- return ResolveUtil.searchChildAssignmentStatements(this, name);
- }
-
- @Nullable
public FunctionStatement findLoadedFunction(String name) {
for (LoadStatement loadStatement : findChildrenByClass(LoadStatement.class)) {
for (LoadedSymbol loadedSymbol : loadStatement.getImportedSymbolElements()) {
@@ -293,6 +244,28 @@
}
@Override
+ public ItemPresentation getPresentation() {
+ final BuildFile element = this;
+ return new ItemPresentation() {
+ @Override
+ public String getPresentableText() {
+ return element.getName();
+ }
+
+ @Override
+ public String getLocationString() {
+ String label = getBuildFileString(element.getProject(), element.getFilePath());
+ return String.format("(%s)", label);
+ }
+
+ @Override
+ public Icon getIcon(boolean unused) {
+ return element.getIcon(0);
+ }
+ };
+ }
+
+ @Override
public String toString() {
return getBuildFileString(getProject(), getFilePath());
}
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..46701da 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,7 @@
*/
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.BuildFile.BlazeFileType;
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;
@@ -106,8 +105,10 @@
@Nullable
public Label resolveBuildLabel() {
BuildFile containingFile = getContainingFile();
- if (containingFile == null
- || containingFile.getBlazeFileType() == BuildFile.BlazeFileType.SkylarkExtension) {
+ if (containingFile == null) {
+ return null;
+ }
+ if (containingFile.getBlazeFileType() != BlazeFileType.BuildPackage) {
return null;
}
return LabelUtils.createLabelFromRuleName(getBlazePackage(), getNameArgumentValue());
@@ -175,11 +176,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/StringLiteral.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/StringLiteral.java
index 027107e..933bd47 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/StringLiteral.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/StringLiteral.java
@@ -18,6 +18,7 @@
import com.google.idea.blaze.base.lang.buildfile.psi.Argument.Keyword;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.google.idea.blaze.base.lang.buildfile.references.AttributeSpecificStringLiteralReferenceProvider;
+import com.google.idea.blaze.base.lang.buildfile.references.ExternalWorkspaceReferenceFragment;
import com.google.idea.blaze.base.lang.buildfile.references.LabelReference;
import com.google.idea.blaze.base.lang.buildfile.references.LoadedSymbolReference;
import com.google.idea.blaze.base.lang.buildfile.references.PackageReferenceFragment;
@@ -128,8 +129,11 @@
}
PsiReference primaryReference = getReference();
if (primaryReference instanceof LabelReference) {
+ LabelReference labelReference = (LabelReference) primaryReference;
return new PsiReference[] {
- primaryReference, new PackageReferenceFragment((LabelReference) primaryReference)
+ primaryReference,
+ new PackageReferenceFragment(labelReference),
+ new ExternalWorkspaceReferenceFragment(labelReference)
};
}
return primaryReference != null
@@ -159,7 +163,7 @@
/** If this string is an attribute value within a BUILD rule, return the attribute type. */
@Nullable
private String getParentAttributeName() {
- Keyword parentKeyword = PsiUtils.getParentOfType(this, Keyword.class);
+ Keyword parentKeyword = PsiUtils.getParentOfType(this, Keyword.class, true);
return parentKeyword != null ? parentKeyword.getName() : null;
}
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/psi/util/PsiUtils.java b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/util/PsiUtils.java
index 30d8c5e..213586b 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/psi/util/PsiUtils.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/psi/util/PsiUtils.java
@@ -67,13 +67,14 @@
* a parent of type PsiDirectory.
*/
@Nullable
- public static <T extends PsiElement> T getParentOfType(PsiElement element, Class<T> psiClass) {
- PsiElement parent = element.getParent();
- while (parent != null && !(parent instanceof PsiDirectory)) {
- if (psiClass.isInstance(parent)) {
- return (T) parent;
+ public static <T extends PsiElement> T getParentOfType(
+ PsiElement element, Class<T> psiClass, boolean strict) {
+ element = strict ? element.getParent() : element;
+ while (element != null && !(element instanceof PsiDirectory)) {
+ if (psiClass.isInstance(element)) {
+ return psiClass.cast(element);
}
- parent = parent.getParent();
+ element = element.getParent();
}
return null;
}
@@ -159,7 +160,7 @@
* Unwraps ParenthesizedExpression.<br>
* For other types, returns the input expression.
*/
- public static PsiElement getReferencedTarget(Expression expr) {
+ private static PsiElement getReferencedTarget(Expression expr) {
PsiElement element = expr;
while (true) {
PsiElement unwrapped = unwrap(element);
@@ -170,6 +171,7 @@
}
}
+ @Nullable
private static PsiElement unwrap(PsiElement expr) {
if (expr instanceof ParenthesizedExpression) {
return ((ParenthesizedExpression) expr).getContainedExpression();
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..2fdb3a3
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/quickfix/DeprecatedLoadQuickFix.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 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.lang.buildfile.references.LabelUtils;
+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("/") || LabelUtils.isAbsolute(contents)) {
+ 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 + ".bzl";
+
+ 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/refactor/BuildNamesValidator.java b/base/src/com/google/idea/blaze/base/lang/buildfile/refactor/BuildNamesValidator.java
index f85425d..ded303f 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/refactor/BuildNamesValidator.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/refactor/BuildNamesValidator.java
@@ -15,18 +15,24 @@
*/
package com.google.idea.blaze.base.lang.buildfile.refactor;
+import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.lang.buildfile.lexer.BuildLexer;
import com.google.idea.blaze.base.lang.buildfile.lexer.BuildLexerBase;
import com.google.idea.blaze.base.lang.buildfile.lexer.TokenKind;
import com.intellij.lang.refactoring.NamesValidator;
import com.intellij.openapi.project.Project;
+import java.util.stream.Collectors;
-/** Used for rename validation */
+/** Used for rename validation of elements which aren't string literals. */
public class BuildNamesValidator implements NamesValidator {
+ private static final ImmutableSet<String> KEYWORDS =
+ ImmutableSet.copyOf(
+ TokenKind.KEYWORDS.stream().map(TokenKind::toString).collect(Collectors.toSet()));
+
@Override
public boolean isKeyword(String s, Project project) {
- return false;
+ return KEYWORDS.contains(s);
}
@Override
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/refactor/TargetRenameValidator.java b/base/src/com/google/idea/blaze/base/lang/buildfile/refactor/TargetRenameValidator.java
new file mode 100644
index 0000000..a46ccad
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/refactor/TargetRenameValidator.java
@@ -0,0 +1,39 @@
+/*
+ * 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.refactor;
+
+import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
+import com.google.idea.blaze.base.model.primitives.TargetName;
+import com.intellij.patterns.ElementPattern;
+import com.intellij.patterns.PlatformPatterns;
+import com.intellij.psi.PsiElement;
+import com.intellij.refactoring.rename.RenameInputValidator;
+import com.intellij.util.ProcessingContext;
+
+/** Overrides name validation for target names. */
+public class TargetRenameValidator implements RenameInputValidator {
+
+ @Override
+ public ElementPattern<? extends PsiElement> getPattern() {
+ // FuncallExpression is the owner of the target name.
+ return PlatformPatterns.psiElement(FuncallExpression.class);
+ }
+
+ @Override
+ public boolean isInputValid(String newName, PsiElement element, ProcessingContext context) {
+ return TargetName.validate(newName);
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/BuildReferenceManager.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/BuildReferenceManager.java
index 9b72b1d..4738bdd 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/BuildReferenceManager.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/BuildReferenceManager.java
@@ -25,6 +25,7 @@
import com.google.idea.blaze.base.model.primitives.TargetName;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.sync.workspace.WorkspaceHelper;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverProvider;
import com.intellij.openapi.components.ServiceManager;
@@ -58,19 +59,19 @@
/** Finds the PSI element associated with the given label. */
@Nullable
public PsiElement resolveLabel(Label label) {
- return resolveLabel(label.blazePackage(), label.targetName(), false);
+ return resolveLabel(label, false);
}
/** Finds the PSI element associated with the given label. */
@Nullable
- public PsiElement resolveLabel(
- WorkspacePath packagePath, TargetName targetName, boolean excludeRules) {
- File packageDir = resolvePackage(packagePath);
+ public PsiElement resolveLabel(Label label, boolean excludeRules) {
+ File packageDir = WorkspaceHelper.resolveBlazePackage(project, label);
if (packageDir == null) {
return null;
}
- if (targetName.toString().equals("__pkg__")) {
+ String targetName = label.targetName().toString();
+ if (targetName.equals("__pkg__")) {
return findBuildFile(packageDir);
}
@@ -82,7 +83,7 @@
}
// try a direct file reference (e.g. ":a.java")
- File fullFile = new File(packageDir, targetName.toString());
+ File fullFile = new File(packageDir, targetName);
if (FileAttributeProvider.getInstance().exists(fullFile)) {
return resolveFile(fullFile);
}
@@ -90,9 +91,9 @@
return null;
}
- private FuncallExpression findRule(File packageDir, TargetName targetName) {
+ private FuncallExpression findRule(File packageDir, String targetName) {
BuildFile psiFile = findBuildFile(packageDir);
- return psiFile != null ? psiFile.findRule(targetName.toString()) : null;
+ return psiFile != null ? psiFile.findRule(targetName) : null;
}
@Nullable
@@ -190,7 +191,8 @@
}
private BuildLookupElement lookupForFile(VirtualFile file, FileLookupData lookupData) {
- WorkspacePath workspacePath = getWorkspaceRelativePath(file.getPath());
+ WorkspacePath workspacePath =
+ WorkspaceHelper.resolveWorkspacePath(project, new File(file.getPath()));
return lookupData.lookupElementForFile(project, file, workspacePath);
}
@@ -244,10 +246,4 @@
String rulePathParent = PathUtil.getParentPath(targetName.toString());
return new File(packageFile, rulePathParent);
}
-
- @Nullable
- public WorkspacePath getWorkspaceRelativePath(String absolutePath) {
- WorkspacePathResolver pathResolver = getWorkspacePathResolver();
- return pathResolver != null ? pathResolver.getWorkspacePath(new File(absolutePath)) : null;
- }
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/ExternalWorkspaceReferenceFragment.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/ExternalWorkspaceReferenceFragment.java
new file mode 100644
index 0000000..521f432
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/ExternalWorkspaceReferenceFragment.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.base.lang.buildfile.references;
+
+import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
+import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
+import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
+import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
+import com.google.idea.blaze.base.model.primitives.WorkspacePath;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.intellij.lang.ASTNode;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFileSystemItem;
+import com.intellij.psi.PsiReferenceBase;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ObjectUtils;
+import javax.annotation.Nullable;
+
+/** The external workspace component of a label (between '@' and '//') */
+public class ExternalWorkspaceReferenceFragment extends PsiReferenceBase<StringLiteral> {
+
+ public ExternalWorkspaceReferenceFragment(LabelReference labelReference) {
+ super(labelReference.getElement(), labelReference.getRangeInElement(), labelReference.isSoft());
+ }
+
+ @Override
+ public TextRange getRangeInElement() {
+ String rawText = myElement.getText();
+ boolean valid = LabelUtils.getExternalWorkspaceComponent(myElement.getStringContents()) != null;
+ if (!valid) {
+ return TextRange.EMPTY_RANGE;
+ }
+ int endIndex = rawText.indexOf("//");
+ if (endIndex == -1) {
+ endIndex = rawText.length() - 1;
+ }
+ return new TextRange(1, endIndex);
+ }
+
+ @Nullable
+ @Override
+ public FuncallExpression resolve() {
+ String name = LabelUtils.getExternalWorkspaceComponent(myElement.getStringContents());
+ if (name == null) {
+ return null;
+ }
+ BuildFile workspaceFile = resolveProjectWorkspaceFile(myElement.getProject());
+ return workspaceFile != null ? workspaceFile.findRule(name) : null;
+ }
+
+ @Nullable
+ private static BuildFile resolveProjectWorkspaceFile(Project project) {
+ WorkspaceRoot projectRoot = WorkspaceRoot.fromProject(project);
+ if (projectRoot == null) {
+ return null;
+ }
+ PsiFileSystemItem workspaceFile =
+ BuildReferenceManager.getInstance(project)
+ .resolveFile(projectRoot.fileForPath(new WorkspacePath("WORKSPACE")));
+ return ObjectUtils.tryCast(workspaceFile, BuildFile.class);
+ }
+
+ @Override
+ public Object[] getVariants() {
+ return EMPTY_ARRAY;
+ }
+
+ @Override
+ public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
+ String oldString = myElement.getStringContents();
+ int slashesIndex = oldString.indexOf("//");
+ String newString =
+ String.format(
+ "@%s%s", newElementName, slashesIndex == -1 ? "" : oldString.substring(slashesIndex));
+ return handleRename(newString);
+ }
+
+ @Override
+ public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException {
+ return myElement;
+ }
+
+ private PsiElement handleRename(String newStringContents) {
+ ASTNode node = myElement.getNode();
+ node.replaceChild(
+ node.getFirstChildNode(),
+ PsiUtils.createNewLabel(myElement.getProject(), newStringContents));
+ return myElement;
+ }
+}
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..36ae50c 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
@@ -19,6 +19,7 @@
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.search.BlazePackage;
+import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.icons.AllIcons;
@@ -32,8 +33,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 {
@@ -89,11 +90,14 @@
StringLiteral element,
@Nullable BuildFile basePackage,
@Nullable VirtualFileFilter fileFilter) {
- String basePackagePath =
- basePackage != null ? basePackage.getWorkspaceRelativePackagePath() : null;
- if (basePackagePath == null) {
+ if (basePackage == null) {
return null;
}
+ Label packageLabel = basePackage.getPackageLabel();
+ if (packageLabel == null) {
+ return null;
+ }
+ String basePackagePath = packageLabel.blazePackage().relativePath();
String filePath = basePackagePath + "/" + LabelUtils.getRuleComponent(originalLabel);
return new FileLookupData(
originalLabel,
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/GlobReference.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/GlobReference.java
index c3ddb46..1f349c1 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/GlobReference.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/GlobReference.java
@@ -17,7 +17,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-import com.google.idea.blaze.base.io.FileAttributeProvider;
+import com.google.idea.blaze.base.bazel.BuildSystemProvider;
import com.google.idea.blaze.base.lang.buildfile.globbing.UnixGlob;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.Expression;
@@ -25,7 +25,9 @@
import com.google.idea.blaze.base.lang.buildfile.psi.ListLiteral;
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.settings.Blaze;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementResolveResult;
@@ -109,19 +111,19 @@
if (includes.isEmpty()) {
return ResolveResult.EMPTY_ARRAY;
}
-
+ Project project = element.getProject();
try {
List<File> files =
UnixGlob.forPath(containingDirectory)
.addPatterns(includes)
.addExcludes(excludes)
.setExcludeDirectories(directoriesExcluded)
- .setDirectoryFilter(directoryFilter(containingDirectory.getPath()))
+ .setDirectoryFilter(directoryFilter(project, containingDirectory.getPath()))
.glob();
+
List<ResolveResult> results = Lists.newArrayListWithCapacity(files.size());
for (File file : files) {
- PsiFileSystemItem psiFile =
- BuildReferenceManager.getInstance(element.getProject()).resolveFile(file);
+ PsiFileSystemItem psiFile = BuildReferenceManager.getInstance(project).resolveFile(file);
if (psiFile != null) {
results.add(new PsiElementResolveResult(psiFile));
}
@@ -133,14 +135,14 @@
}
}
- private static Predicate<File> directoryFilter(String base) {
+ /** Don't traverse sub-directories which are themselves blaze packages */
+ private static Predicate<File> directoryFilter(Project project, String base) {
+ BuildSystemProvider provider = Blaze.getBuildSystemProvider(project);
return file -> {
if (base.equals(file.getPath())) {
return true;
}
- File child = new File(file, "BUILD");
- FileAttributeProvider attributeProvider = FileAttributeProvider.getInstance();
- return !attributeProvider.exists(child) || attributeProvider.isDirectory(child);
+ return provider.findBuildFileInDirectory(file) == null;
};
}
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..a3457bb 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,7 @@
import com.intellij.psi.PsiReferenceBase;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import javax.annotation.Nullable;
/** Converts a blaze label into an absolute path, then resolves that path to a PsiElements */
public class LabelReference extends PsiReferenceBase<StringLiteral> {
@@ -51,7 +50,7 @@
/* Possibilities:
* - target
* - data file (.java, .txt, etc.)
- * - glob contents (not yet handling globs)
+ * - glob contents
*/
return resolveTarget(myElement.getStringContents());
}
@@ -65,8 +64,8 @@
if (!validLabelLocation(myElement)) {
return null;
}
- if (!labelString.startsWith("//") && insideSkylarkExtension(myElement)) {
- return getReferenceManager().resolveLabel(label.blazePackage(), label.targetName(), true);
+ if (!LabelUtils.isAbsolute(labelString) && insideSkylarkExtension(myElement)) {
+ return getReferenceManager().resolveLabel(label, true);
}
return getReferenceManager().resolveLabel(label);
}
@@ -86,7 +85,6 @@
return true;
}
- @NotNull
@Override
public Object[] getVariants() {
if (!validLabelLocation(myElement)) {
@@ -110,7 +108,8 @@
}
String self = null;
if (referencedBuildFile == myElement.getContainingFile()) {
- FuncallExpression funcall = PsiUtils.getParentOfType(myElement, FuncallExpression.class);
+ FuncallExpression funcall =
+ PsiUtils.getParentOfType(myElement, FuncallExpression.class, true);
if (funcall != null) {
self = funcall.getName();
}
@@ -242,8 +241,7 @@
return null;
}
BlazePackage blazePackage = myElement.getBlazePackage();
- return LabelUtils.createLabelFromString(
- blazePackage != null ? blazePackage.buildFile : null, labelString);
+ return LabelUtils.createLabelFromString(blazePackage, labelString);
}
private static boolean skylarkExtensionReference(StringLiteral element) {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/references/LabelUtils.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/LabelUtils.java
index db58991..cf3e8df 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/LabelUtils.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/LabelUtils.java
@@ -54,8 +54,8 @@
if (blazePackage == null || ruleName == null) {
return null;
}
- WorkspacePath packagePath = blazePackage.buildFile.getPackageWorkspacePath();
- return createLabelFromRuleName(packagePath, ruleName);
+ Label packageLabel = blazePackage.buildFile.getPackageLabel();
+ return packageLabel != null ? packageLabel.withTargetName(ruleName) : null;
}
public static Label createLabelFromRuleName(
@@ -67,36 +67,35 @@
if (packagePath == null || name == null) {
return null;
}
- // TODO: Is Label too inefficient?
- // (validation done twice,creating List during constructor,
- // re-parsing to extract the package/rule each time)
- return new Label(packagePath, name);
+ return Label.create(packagePath, name);
}
/**
- * Canonicalizes the label (to the form //packagePath:packageRelativeTarget). Returns null if the
- * string does not represent a valid label.
+ * Canonicalizes the label (to the form [@external_workspace]//packagePath:packageRelativeTarget).
+ * Returns null if the string does not represent a valid label.
*/
@Nullable
public static Label createLabelFromString(
- @Nullable BuildFile file, @Nullable String labelString) {
+ @Nullable BlazePackage blazePackage, @Nullable String labelString) {
if (labelString == null) {
return null;
}
int colonIndex = labelString.indexOf(':');
- if (labelString.startsWith("//")) {
+ if (isAbsolute(labelString)) {
if (colonIndex == -1) {
// add the implicit rule name
labelString += ":" + PathUtil.getFileName(labelString);
}
return Label.createIfValid(labelString);
}
- WorkspacePath packagePath = file != null ? file.getPackageWorkspacePath() : null;
- if (packagePath == null) {
+ // package-relative label of the form '[:]relativePath'
+ if (colonIndex > 0 || blazePackage == null) {
return null;
}
- String localPath = colonIndex == -1 ? labelString : labelString.substring(1);
- return Label.createIfValid("//" + packagePath.relativePath() + ":" + localPath);
+ Label packageLabel = blazePackage.getPackageLabel();
+ return packageLabel != null
+ ? packageLabel.withTargetName(labelString.substring(colonIndex + 1))
+ : null;
}
/** The blaze file referenced by the label. */
@@ -121,12 +120,33 @@
return labelString.startsWith(":") ? labelString.substring(1) : labelString;
}
+ /** For a label of the form '[@ext]//package/path:target/name', returns '//package/path' */
public static String getPackagePathComponent(String labelString) {
- if (!labelString.startsWith("//")) {
+ if (!isAbsolute(labelString)) {
+ return "";
+ }
+ int slashesIndex = labelString.indexOf("//");
+ if (slashesIndex == -1) {
return "";
}
int colonIndex = labelString.indexOf(':');
- return colonIndex == -1 ? labelString : labelString.substring(0, colonIndex);
+ return colonIndex == -1
+ ? labelString.substring(slashesIndex)
+ : labelString.substring(slashesIndex, colonIndex);
+ }
+
+ @Nullable
+ public static String getExternalWorkspaceComponent(String labelString) {
+ if (!labelString.startsWith("@")) {
+ return null;
+ }
+ int slashesIndex = labelString.indexOf("//");
+ return slashesIndex == -1 ? null : labelString.substring(1, slashesIndex);
+ }
+
+ /** Returns false for package-relative labels */
+ public static boolean isAbsolute(String labelString) {
+ return labelString.startsWith("//") || labelString.startsWith("@");
}
/** 'load' reference. Of the form [path][/ or :][extra_path/]file_name.bzl */
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/PackageReferenceFragment.java b/base/src/com/google/idea/blaze/base/lang/buildfile/references/PackageReferenceFragment.java
index 6dba496..746d4e5 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/references/PackageReferenceFragment.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/references/PackageReferenceFragment.java
@@ -18,6 +18,7 @@
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.Label;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
@@ -27,7 +28,7 @@
import com.intellij.util.PathUtil;
import javax.annotation.Nullable;
-/** The label component preceeding the colon. */
+/** The label component preceding the colon. */
public class PackageReferenceFragment extends PsiReferenceBase<StringLiteral> {
public PackageReferenceFragment(LabelReference labelReference) {
@@ -84,10 +85,11 @@
if (element.equals(resolve())) {
return myElement;
}
- WorkspacePath newPath = ((BuildFile) element).getPackageWorkspacePath();
- if (newPath == null) {
+ Label newPackageLabel = ((BuildFile) element).getPackageLabel();
+ if (newPackageLabel == null) {
return myElement;
}
+ String newPath = newPackageLabel.blazePackage().toString();
String labelString = myElement.getStringContents();
int colonIndex = labelString.indexOf(':');
if (colonIndex != -1) {
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..94f2f48 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,13 @@
*/
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.model.primitives.Label;
import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.sync.workspace.WorkspaceHelper;
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;
@@ -30,7 +33,10 @@
import java.util.Objects;
import javax.annotation.Nullable;
-/** Defines the files accessible by a given blaze package. */
+/**
+ * A Blaze package is a directory containing a BUILD file, plus all subdirectories which aren't
+ * themselves Blaze packages.
+ */
public class BlazePackage {
@Nullable
@@ -96,6 +102,11 @@
return new BlazePackageSearchScope(this, onlyBlazeFiles);
}
+ @Nullable
+ public Label getPackageLabel() {
+ return WorkspaceHelper.getBuildLabel(buildFile.getProject(), buildFile.getFile());
+ }
+
/**
* Returns the file path relative to this blaze package, or null if it does lie inside this
* package
@@ -108,19 +119,13 @@
/** Formats the child file path as a BUILD label (i.e. "//package_path[:relative_path]") */
@Nullable
- public String getBuildLabelForChild(String filePath) {
- WorkspacePath packagePath = buildFile.getPackageWorkspacePath();
- if (packagePath == null) {
+ public Label getBuildLabelForChild(String filePath) {
+ Label parentPackage = getPackageLabel();
+ if (parentPackage == null) {
return null;
}
String relativePath = getPackageRelativePath(filePath);
- if (relativePath == null) {
- return null;
- }
- if (relativePath.isEmpty()) {
- return "//" + packagePath;
- }
- return "//" + packagePath + ":" + relativePath;
+ return parentPackage.withTargetName(relativePath);
}
/**
@@ -190,6 +195,29 @@
public String toString() {
return String.format(
"%s package: %s",
- Blaze.buildSystemName(buildFile.getProject()), buildFile.getPackageWorkspacePath());
+ Blaze.buildSystemName(buildFile.getProject()), buildFile.getPackageLabel());
+ }
+
+ 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/BlazePackageSearchScope.java b/base/src/com/google/idea/blaze/base/lang/buildfile/search/BlazePackageSearchScope.java
index d5f6606..841ad88 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/search/BlazePackageSearchScope.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/search/BlazePackageSearchScope.java
@@ -65,7 +65,7 @@
public String toString() {
return String.format(
"%s directory scope: %s",
- Blaze.buildSystemName(getProject()), blazePackage.buildFile.getPackageWorkspacePath());
+ Blaze.buildSystemName(getProject()), blazePackage.buildFile.getPackageLabel());
}
@Override
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 78%
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..d35fc90 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,11 +20,10 @@
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;
-import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
@@ -39,41 +38,45 @@
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);
return;
}
-
if (!(element instanceof FuncallExpression)) {
return;
}
-
- Label label = ((FuncallExpression) element).resolveBuildLabel();
+ FuncallExpression funcall = (FuncallExpression) element;
PsiFile localFile = element.getContainingFile();
- if (label == null || localFile == null) {
+ if (localFile == null) {
+ return;
+ }
+ Label label = funcall.resolveBuildLabel();
+ if (label == null) {
+ searchForExternalWorkspace(params, localFile, funcall);
return;
}
List<String> stringsToSearch = LabelUtils.getAllValidLabelStrings(label, true);
for (String string : stringsToSearch) {
- if (string.startsWith("//")) {
+ if (LabelUtils.isAbsolute(string)) {
searchForString(params, element, string);
} else {
// only a valid reference from local package -- restrict the search scope accordingly
@@ -117,17 +120,18 @@
/** Find references to both the file itself, and build targets defined in the file. */
private void processBuildFileReferences(SearchParameters params, BuildFile file) {
- WorkspacePath workspacePath = file.getPackageWorkspacePath();
- if (workspacePath == null) {
+ Label label = file.getBuildLabel();
+ if (label == null) {
return;
}
+ String labelString = label.toString();
List<String> stringsToSearch = Lists.newArrayList();
if (file.getBlazeFileType() == BlazeFileType.BuildPackage) {
- stringsToSearch.add("//" + workspacePath);
+ // remove ':__pkg__' component of label
+ stringsToSearch.add(labelString.split(":", 2)[0]);
} else {
- stringsToSearch.add("//" + workspacePath + ":" + file.getName());
- stringsToSearch.add(
- "//" + workspacePath + "/" + file.getName()); // deprecated load/subinclude format
+ stringsToSearch.add(labelString);
+ stringsToSearch.add(labelString.replace(':', '/')); // deprecated load/subinclude format
}
for (String string : stringsToSearch) {
searchForString(params, file, string);
@@ -161,4 +165,21 @@
}
params.getOptimizer().searchWord(string, scope, UsageSearchContext.IN_STRINGS, true, element);
}
+
+ private static void searchForExternalWorkspace(
+ SearchParameters params, PsiFile file, FuncallExpression funcall) {
+ if (!isBlazeWorkspaceFile(file)) {
+ return;
+ }
+ String name = funcall.getNameArgumentValue();
+ if (name != null) {
+ searchForString(params, funcall, "@" + name);
+ }
+ }
+
+ /** Is the file a blaze WORKSPACE file */
+ private static boolean isBlazeWorkspaceFile(PsiFile file) {
+ return file instanceof BuildFile
+ && ((BuildFile) file).getBlazeFileType() == BlazeFileType.Workspace;
+ }
}
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..4a0f12b 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,9 +15,10 @@
*/
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.command.info.BlazeInfoRunner;
import com.google.idea.blaze.base.ideinfo.TargetMap;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpec;
import com.google.idea.blaze.base.model.SyncState;
@@ -30,7 +31,6 @@
import com.google.idea.blaze.base.sync.BlazeSyncPlugin;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
-import com.google.idea.blaze.base.sync.workspace.BlazeRoots;
import com.google.idea.blaze.base.sync.workspace.WorkingSet;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.google.repackaged.devtools.build.lib.query2.proto.proto2api.Build;
@@ -53,7 +53,7 @@
WorkspaceRoot workspaceRoot,
ProjectViewSet projectViewSet,
WorkspaceLanguageSettings workspaceLanguageSettings,
- BlazeRoots blazeRoots,
+ BlazeInfo blazeInfo,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
ArtifactLocationDecoder artifactLocationDecoder,
@@ -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,17 +97,20 @@
@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)
ListenableFuture<byte[]> future =
- BlazeInfo.getInstance()
+ BlazeInfoRunner.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/BuildElementValidation.java b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildElementValidation.java
index 138908c..d8a8206 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildElementValidation.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildElementValidation.java
@@ -15,6 +15,7 @@
*/
package com.google.idea.blaze.base.lang.buildfile.validation;
+import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.lang.buildfile.psi.DictionaryLiteral;
import com.google.idea.blaze.base.lang.buildfile.psi.FunctionStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.GlobExpression;
@@ -38,14 +39,21 @@
private static final EnumSet<Build.Attribute.Discriminator> LIST_TYPES =
EnumSet.of(
Discriminator.STRING_LIST,
+ Discriminator.DISTRIBUTION_SET,
Discriminator.LABEL_LIST,
Discriminator.OUTPUT_LIST,
Discriminator.FILESET_ENTRY_LIST,
Discriminator.INTEGER_LIST,
- Discriminator.LICENSE);
+ Discriminator.LICENSE,
+ Discriminator.SELECTOR_LIST);
private static final EnumSet<Build.Attribute.Discriminator> DICT_TYPES =
- EnumSet.of(Discriminator.LABEL_LIST_DICT, Discriminator.STRING_LIST_DICT);
+ EnumSet.of(
+ Discriminator.LABEL_LIST_DICT,
+ Discriminator.LABEL_KEYED_STRING_DICT,
+ Discriminator.STRING_DICT,
+ Discriminator.STRING_LIST_DICT,
+ Discriminator.LABEL_DICT_UNARY);
private static final EnumSet<Build.Attribute.Discriminator> STRING_TYPES =
EnumSet.of(
@@ -58,9 +66,20 @@
private static final EnumSet<Build.Attribute.Discriminator> INTEGER_TYPES =
EnumSet.of(Discriminator.INTEGER, Discriminator.BOOLEAN, Discriminator.TRISTATE);
+ // This enum list is duplicated several times through Bazel source code. In some places there are
+ // additional items not covered here. Don't show spurious errors when more items are added.
+ private static final EnumSet<Build.Attribute.Discriminator> HANDLED_TYPES =
+ EnumSet.copyOf(
+ ImmutableList.<Discriminator>builder()
+ .addAll(LIST_TYPES)
+ .addAll(DICT_TYPES)
+ .addAll(STRING_TYPES)
+ .addAll(INTEGER_TYPES)
+ .build());
+
/** Returns false iff we know with certainty that the element cannot resolve to the given type. */
public static boolean possiblyValidType(PsiElement element, Build.Attribute.Discriminator type) {
- if (type == Discriminator.UNKNOWN) {
+ if (!HANDLED_TYPES.contains(type)) {
return true;
}
if (element instanceof ListLiteral || element instanceof GlobExpression) {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuiltInRuleAnnotator.java b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuiltInRuleAnnotator.java
index 48f8136..8fa0362 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuiltInRuleAnnotator.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuiltInRuleAnnotator.java
@@ -43,8 +43,16 @@
if (rule == null) {
return;
}
+ if (node.getReferencedElement() != null) {
+ // this has been locally overridden, so don't attempt validation
+ return;
+ }
Set<String> missingAttributes = new TreeSet<>(rule.mandatoryAttributes.keySet());
for (Argument arg : node.getArguments()) {
+ if (arg instanceof Argument.StarStar) {
+ missingAttributes.clear();
+ continue;
+ }
String name = arg.getName();
if (name == null) {
continue;
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/GlobPatternValidator.java b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/GlobPatternValidator.java
index c82d736..f039e31 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/GlobPatternValidator.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/GlobPatternValidator.java
@@ -20,16 +20,12 @@
/**
* Support for resolving globs.
- *
- * <p>
*/
public class GlobPatternValidator {
/**
* Validate a single glob pattern. If it's invalid, returns an error message. Otherwise, returns
* null.
- *
- * <p>
*/
@Nullable
public static String validate(String pattern) {
@@ -58,6 +54,7 @@
case '[':
case ']':
return "illegal character '" + c + "'";
+ default: // fall out
}
}
Iterable<String> segments = Splitter.on('/').split(pattern);
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..c51ccc8
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/LoadStatementAnnotator.java
@@ -0,0 +1,77 @@
+/*
+ * 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.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/AdditionalLanguagesCompletionContributor.java b/base/src/com/google/idea/blaze/base/lang/projectview/completion/AdditionalLanguagesCompletionContributor.java
index 4cf2f36..598372f 100644
--- a/base/src/com/google/idea/blaze/base/lang/projectview/completion/AdditionalLanguagesCompletionContributor.java
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/completion/AdditionalLanguagesCompletionContributor.java
@@ -17,10 +17,14 @@
import static com.intellij.patterns.PlatformPatterns.psiElement;
+import com.google.common.collect.Ordering;
import com.google.idea.blaze.base.lang.projectview.language.ProjectViewLanguage;
import com.google.idea.blaze.base.lang.projectview.psi.ProjectViewPsiListSection;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
+import com.google.idea.blaze.base.model.primitives.WorkspaceType;
import com.google.idea.blaze.base.projectview.section.sections.AdditionalLanguagesSection;
+import com.google.idea.blaze.base.sync.SyncCache;
+import com.google.idea.blaze.base.sync.projectview.LanguageSupport;
import com.intellij.codeInsight.completion.AutoCompletionContext;
import com.intellij.codeInsight.completion.AutoCompletionDecision;
import com.intellij.codeInsight.completion.CompletionContributor;
@@ -30,8 +34,11 @@
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
+import com.intellij.openapi.project.Project;
import com.intellij.patterns.StandardPatterns;
import com.intellij.util.ProcessingContext;
+import java.util.List;
+import java.util.stream.Collectors;
/** Code completion for additional language types. */
public class AdditionalLanguagesCompletionContributor extends CompletionContributor {
@@ -62,10 +69,28 @@
CompletionParameters parameters,
ProcessingContext context,
CompletionResultSet result) {
- for (LanguageClass type : LanguageClass.values()) {
+ for (LanguageClass type :
+ availableAdditionalLanguages(parameters.getEditor().getProject())) {
result.addElement(LookupElementBuilder.create(type.getName()));
}
}
});
}
+
+ private static List<LanguageClass> availableAdditionalLanguages(Project project) {
+ List<LanguageClass> langs =
+ SyncCache.getInstance(project)
+ .get(
+ AdditionalLanguagesCompletionContributor.class,
+ (proj, projectData) ->
+ additionalLanguages(projectData.workspaceLanguageSettings.getWorkspaceType()));
+ return langs == null ? additionalLanguages(LanguageSupport.getDefaultWorkspaceType()) : langs;
+ }
+
+ private static List<LanguageClass> additionalLanguages(WorkspaceType workspaceType) {
+ return LanguageSupport.availableAdditionalLanguages(workspaceType)
+ .stream()
+ .sorted(Ordering.usingToString())
+ .collect(Collectors.toList());
+ }
}
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/documentation/ProjectViewDocumentationProvider.java b/base/src/com/google/idea/blaze/base/lang/projectview/documentation/ProjectViewDocumentationProvider.java
new file mode 100644
index 0000000..fda1879
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/documentation/ProjectViewDocumentationProvider.java
@@ -0,0 +1,141 @@
+/*
+ * 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.projectview.documentation;
+
+import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
+import com.google.idea.blaze.base.lang.projectview.psi.ProjectViewSection;
+import com.google.idea.blaze.base.projectview.section.SectionParser;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.intellij.lang.documentation.AbstractDocumentationProvider;
+import com.intellij.lang.documentation.ExternalDocumentationProvider;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.HeadMethod;
+import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
+
+/** Provides quick docs for some .blazeproject elements. */
+public class ProjectViewDocumentationProvider extends AbstractDocumentationProvider
+ implements ExternalDocumentationProvider {
+
+ @Nullable
+ private static SectionParser getSection(PsiElement element) {
+ ProjectViewSection section = PsiUtils.getParentOfType(element, ProjectViewSection.class, false);
+ return section != null ? section.getSectionParser() : null;
+ }
+
+ @Nullable
+ @Override
+ public String generateDoc(PsiElement element, @Nullable PsiElement originalElement) {
+ SectionParser section = getSection(element);
+ if (section == null) {
+ return null;
+ }
+ StringBuilder builder = new StringBuilder();
+ String quickDocs = section.quickDocs();
+ if (quickDocs != null) {
+ builder.append(wrapInTag("<p>" + section.quickDocs(), "code"));
+ }
+ String url = getUrlFor(element.getProject(), section, false);
+ if (url != null) {
+ builder.append(
+ String.format("<p><b>External documentation</b>:<br><a href=\"%s\">%s</a>", url, url));
+ }
+ return wrapInTag(wrapInTag(builder.toString(), "body"), "html");
+ }
+
+ private static String wrapInTag(String doc, String htmlTag) {
+ return String.format("<%s>%s</%s>", htmlTag, doc, htmlTag);
+ }
+
+ @Override
+ public boolean hasDocumentationFor(PsiElement element, PsiElement originalElement) {
+ return getUrlFor(element, false) != null;
+ }
+
+ @Override
+ public List<String> getUrlFor(PsiElement element, PsiElement originalElement) {
+ final String url = getUrlFor(element, true);
+ return url == null ? null : Collections.singletonList(url);
+ }
+
+ @Nullable
+ @Override
+ public String fetchExternalDocumentation(
+ Project project, PsiElement element, List<String> docUrls) {
+ return null;
+ }
+
+ @Override
+ public boolean canPromptToConfigureDocumentation(PsiElement element) {
+ return false;
+ }
+
+ @Override
+ public void promptToConfigureDocumentation(PsiElement element) {}
+
+ @Nullable
+ private static String getUrlFor(PsiElement element, boolean checkExistence) {
+ SectionParser section = getSection(element);
+ return section != null ? getUrlFor(element.getProject(), section, checkExistence) : null;
+ }
+
+ @Nullable
+ private static String getUrlFor(Project project, SectionParser section, boolean checkExistence) {
+ String baseDocsUrl = Blaze.getBuildSystemProvider(project).getProjectViewDocumentationUrl();
+ if (baseDocsUrl == null) {
+ return null;
+ }
+ String url = baseDocsUrl + "#" + section.getName();
+ if (checkExistence && !pageExists(url)) {
+ return baseDocsUrl;
+ }
+ return url;
+ }
+
+ private static boolean pageExists(String url) {
+ final HttpClient client = new HttpClient();
+ final HttpConnectionManagerParams params = client.getHttpConnectionManager().getParams();
+ params.setSoTimeout(5 * 1000);
+ params.setConnectionTimeout(5 * 1000);
+
+ try {
+ final HeadMethod method = new HeadMethod(url);
+ final int rc = client.executeMethod(method);
+ if (rc == 404) {
+ return false;
+ }
+ } catch (IllegalArgumentException e) {
+ return false;
+ } catch (IOException e) {
+ // ignore
+ }
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public PsiElement getCustomDocumentationElement(
+ Editor editor, PsiFile file, @Nullable PsiElement contextElement) {
+ return PsiUtils.getParentOfType(contextElement, ProjectViewSection.class, false);
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/lang/projectview/formatting/ProjectViewCodeStyleSettingsProvider.java b/base/src/com/google/idea/blaze/base/lang/projectview/formatting/ProjectViewCodeStyleSettingsProvider.java
new file mode 100644
index 0000000..3df7613
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/formatting/ProjectViewCodeStyleSettingsProvider.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.lang.projectview.formatting;
+
+import com.google.idea.blaze.base.lang.projectview.language.ProjectViewLanguage;
+import com.intellij.lang.Language;
+import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
+import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
+import javax.annotation.Nullable;
+
+/** Allows blazeproject-specific code style settings */
+public class ProjectViewCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider {
+
+ @Override
+ public Language getLanguage() {
+ return ProjectViewLanguage.INSTANCE;
+ }
+
+ @Override
+ public String getCodeSample(SettingsType settingsType) {
+ return "";
+ }
+
+ @Nullable
+ @Override
+ public CommonCodeStyleSettings getDefaultCommonSettings() {
+ CommonCodeStyleSettings defaultSettings =
+ new CommonCodeStyleSettings(ProjectViewLanguage.INSTANCE);
+ defaultSettings.LINE_COMMENT_AT_FIRST_COLUMN = false;
+ defaultSettings.LINE_COMMENT_ADD_SPACE = true;
+ CommonCodeStyleSettings.IndentOptions indentOptions = defaultSettings.initIndentOptions();
+ indentOptions.TAB_SIZE = 2;
+ indentOptions.INDENT_SIZE = 2;
+ indentOptions.CONTINUATION_INDENT_SIZE = 2;
+ return defaultSettings;
+ }
+}
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/lang/projectview/psi/ProjectViewPsiListSection.java b/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewPsiListSection.java
index d75547a..3d2ad2b 100644
--- a/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewPsiListSection.java
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewPsiListSection.java
@@ -15,12 +15,22 @@
*/
package com.google.idea.blaze.base.lang.projectview.psi;
+import com.google.idea.blaze.base.lang.projectview.lexer.ProjectViewTokenType;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import javax.annotation.Nullable;
/** Psi element for list section. */
-public class ProjectViewPsiListSection extends ProjectViewPsiElement {
+public class ProjectViewPsiListSection extends ProjectViewSection {
public ProjectViewPsiListSection(ASTNode node) {
super(node);
}
+
+ @Nullable
+ @Override
+ public String getSectionName() {
+ PsiElement keyword = findChildByType(ProjectViewTokenType.LIST_KEYWORD);
+ return keyword != null ? keyword.getText() : null;
+ }
}
diff --git a/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewPsiScalarSection.java b/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewPsiScalarSection.java
index 6f03ff4..19819a4 100644
--- a/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewPsiScalarSection.java
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewPsiScalarSection.java
@@ -15,12 +15,22 @@
*/
package com.google.idea.blaze.base.lang.projectview.psi;
+import com.google.idea.blaze.base.lang.projectview.lexer.ProjectViewTokenType;
import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
+import javax.annotation.Nullable;
/** Psi element for scalar section. */
-public class ProjectViewPsiScalarSection extends ProjectViewPsiElement {
+public class ProjectViewPsiScalarSection extends ProjectViewSection {
public ProjectViewPsiScalarSection(ASTNode node) {
super(node);
}
+
+ @Nullable
+ @Override
+ public String getSectionName() {
+ PsiElement keyword = findChildByType(ProjectViewTokenType.SCALAR_KEYWORD);
+ return keyword != null ? keyword.getText() : null;
+ }
}
diff --git a/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewSection.java b/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewSection.java
new file mode 100644
index 0000000..9e275bf
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/psi/ProjectViewSection.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.lang.projectview.psi;
+
+import com.google.idea.blaze.base.projectview.section.SectionParser;
+import com.google.idea.blaze.base.projectview.section.sections.Sections;
+import com.intellij.lang.ASTNode;
+import com.intellij.navigation.ItemPresentation;
+import com.intellij.navigation.NavigationItem;
+import javax.annotation.Nullable;
+import javax.swing.Icon;
+
+/** Psi element for a list or scalar section. */
+public abstract class ProjectViewSection extends ProjectViewPsiElement implements NavigationItem {
+
+ public ProjectViewSection(ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public ItemPresentation getPresentation() {
+ final ProjectViewSection element = this;
+ return new ItemPresentation() {
+ @Override
+ public String getPresentableText() {
+ return getSectionName();
+ }
+
+ @Override
+ public String getLocationString() {
+ return null;
+ }
+
+ @Override
+ public Icon getIcon(boolean unused) {
+ return element.getIcon(0);
+ }
+ };
+ }
+
+ @Override
+ public String getName() {
+ return getSectionName();
+ }
+
+ @Nullable
+ protected abstract String getSectionName();
+
+ @Nullable
+ public SectionParser getSectionParser() {
+ String text = getSectionName();
+ if (text == null) {
+ return null;
+ }
+ for (SectionParser parser : Sections.getParsers()) {
+ if (text.equals(parser.getName())) {
+ return parser;
+ }
+ }
+ return null;
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/lang/projectview/stubs/ProjectViewFileStubBuilder.java b/base/src/com/google/idea/blaze/base/lang/projectview/stubs/ProjectViewFileStubBuilder.java
new file mode 100644
index 0000000..dcf8917
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/lang/projectview/stubs/ProjectViewFileStubBuilder.java
@@ -0,0 +1,43 @@
+/*
+ * 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.projectview.stubs;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.stubs.BinaryFileStubBuilder;
+import com.intellij.psi.stubs.Stub;
+import com.intellij.util.indexing.FileContent;
+import javax.annotation.Nullable;
+
+/** Empty stub builder to suppress errors when IntelliJ is looking for stubs. */
+public class ProjectViewFileStubBuilder implements BinaryFileStubBuilder {
+ private static final int STUB_VERSION = 0;
+
+ @Override
+ public boolean acceptsFile(VirtualFile file) {
+ return false;
+ }
+
+ @Nullable
+ @Override
+ public Stub buildStubTree(FileContent fileContent) {
+ return null;
+ }
+
+ @Override
+ public int getStubVersion() {
+ return STUB_VERSION;
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/logging/EventLogger.java b/base/src/com/google/idea/blaze/base/logging/EventLogger.java
new file mode 100644
index 0000000..02a930f
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/logging/EventLogger.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.logging;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import java.util.Map;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Forwards the event logs to an applicable receiver extension or discard them if no applicable
+ * receivers exist.
+ */
+public interface EventLogger {
+ ExtensionPointName<EventLogger> EP_NAME =
+ new ExtensionPointName<>("com.google.idea.blaze.EventLogger");
+
+ static EventLogger getInstance() {
+ for (EventLogger logger : EP_NAME.getExtensions()) {
+ if (logger.isApplicable()) {
+ return logger;
+ }
+ }
+ return NullEventLogger.SINGLETON;
+ }
+
+ boolean isApplicable();
+
+ default void log(Class<?> loggingClass, String eventType, Map<String, String> keyValues) {
+ log(loggingClass, eventType, keyValues, null);
+ }
+
+ void log(
+ Class<?> loggingClass,
+ String eventType,
+ Map<String, String> keyValues,
+ @Nullable Long durationInNanos);
+}
diff --git a/base/src/com/google/idea/blaze/base/logging/NullEventLogger.java b/base/src/com/google/idea/blaze/base/logging/NullEventLogger.java
new file mode 100644
index 0000000..0546f7b
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/logging/NullEventLogger.java
@@ -0,0 +1,38 @@
+/*
+ * 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.logging;
+
+import java.util.Map;
+import org.jetbrains.annotations.Nullable;
+
+/** No-op logger used when no logger is not available to receive logs. */
+public class NullEventLogger implements EventLogger {
+ static final NullEventLogger SINGLETON = new NullEventLogger();
+
+ private NullEventLogger() {}
+
+ @Override
+ public boolean isApplicable() {
+ return true;
+ }
+
+ @Override
+ public void log(
+ Class<?> loggingClass,
+ String eventType,
+ Map<String, String> keyValues,
+ @Nullable Long durationInNanos) {}
+}
diff --git a/base/src/com/google/idea/blaze/base/model/BlazeProjectData.java b/base/src/com/google/idea/blaze/base/model/BlazeProjectData.java
index 77862fd..bba404b 100644
--- a/base/src/com/google/idea/blaze/base/model/BlazeProjectData.java
+++ b/base/src/com/google/idea/blaze/base/model/BlazeProjectData.java
@@ -15,13 +15,12 @@
*/
package com.google.idea.blaze.base.model;
-import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
+import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.ideinfo.TargetKey;
import com.google.idea.blaze.base.ideinfo.TargetMap;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
-import com.google.idea.blaze.base.sync.workspace.BlazeRoots;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
@@ -29,12 +28,11 @@
/** The top-level object serialized to cache. */
@Immutable
public class BlazeProjectData implements Serializable {
- private static final long serialVersionUID = 27L;
+ private static final long serialVersionUID = 28L;
public final long syncTime;
public final TargetMap targetMap;
- public final ImmutableMap<String, String> blazeInfo;
- public final BlazeRoots blazeRoots;
+ public final BlazeInfo blazeInfo;
public final BlazeVersionData blazeVersionData;
public final WorkspacePathResolver workspacePathResolver;
public final ArtifactLocationDecoder artifactLocationDecoder;
@@ -45,19 +43,16 @@
public BlazeProjectData(
long syncTime,
TargetMap targetMap,
- ImmutableMap<String, String> blazeInfo,
- BlazeRoots blazeRoots,
+ BlazeInfo blazeInfo,
BlazeVersionData blazeVersionData,
WorkspacePathResolver workspacePathResolver,
ArtifactLocationDecoder artifactLocationDecoder,
WorkspaceLanguageSettings workspaceLanguageSettings,
SyncState syncState,
- ImmutableMultimap<TargetKey, TargetKey> reverseDependencies,
- Object dummy) {
+ ImmutableMultimap<TargetKey, TargetKey> reverseDependencies) {
this.syncTime = syncTime;
this.targetMap = targetMap;
this.blazeInfo = blazeInfo;
- this.blazeRoots = blazeRoots;
this.blazeVersionData = blazeVersionData;
this.workspacePathResolver = workspacePathResolver;
this.artifactLocationDecoder = artifactLocationDecoder;
diff --git a/base/src/com/google/idea/blaze/base/model/BlazeVersionData.java b/base/src/com/google/idea/blaze/base/model/BlazeVersionData.java
index 1cbdbff..ded37ad 100644
--- a/base/src/com/google/idea/blaze/base/model/BlazeVersionData.java
+++ b/base/src/com/google/idea/blaze/base/model/BlazeVersionData.java
@@ -16,9 +16,9 @@
package com.google.idea.blaze.base.model;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.bazel.BazelVersion;
import com.google.idea.blaze.base.bazel.BuildSystemProvider;
+import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import java.io.Serializable;
@@ -59,10 +59,12 @@
return bazelVersion != null && bazelVersion.isAtLeast(major, minor, bugfix);
}
+ public BuildSystem buildSystem() {
+ return bazelVersion != null ? BuildSystem.Bazel : BuildSystem.Blaze;
+ }
+
public static BlazeVersionData build(
- BuildSystem buildSystem,
- WorkspaceRoot workspaceRoot,
- ImmutableMap<String, String> blazeInfo) {
+ BuildSystem buildSystem, WorkspaceRoot workspaceRoot, BlazeInfo blazeInfo) {
Builder builder = new Builder();
for (BuildSystemProvider provider : BuildSystemProvider.EP_NAME.getExtensions()) {
provider.populateBlazeVersionData(buildSystem, workspaceRoot, blazeInfo, builder);
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/Kind.java b/base/src/com/google/idea/blaze/base/model/primitives/Kind.java
index eba71f9..b5fbda8 100644
--- a/base/src/com/google/idea/blaze/base/model/primitives/Kind.java
+++ b/base/src/com/google/idea/blaze/base/model/primitives/Kind.java
@@ -15,9 +15,11 @@
*/
package com.google.idea.blaze.base.model.primitives;
+import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
import java.util.Arrays;
-import java.util.List;
+import java.util.Collection;
/** Wrapper around a string for a blaze kind (android_library, android_test...) */
public enum Kind {
@@ -25,6 +27,7 @@
ANDROID_LIBRARY("android_library", LanguageClass.ANDROID),
ANDROID_TEST("android_test", LanguageClass.ANDROID),
ANDROID_ROBOLECTRIC_TEST("android_robolectric_test", LanguageClass.ANDROID),
+ ANDROID_SDK("android_sdk", LanguageClass.ANDROID),
JAVA_LIBRARY("java_library", LanguageClass.JAVA),
JAVA_TEST("java_test", LanguageClass.JAVA),
JAVA_BINARY("java_binary", LanguageClass.JAVA),
@@ -57,10 +60,16 @@
GO_APPENGINE_LIBRARY("go_appengine_library", LanguageClass.GO),
GO_WRAP_CC("go_wrap_cc", LanguageClass.GO),
INTELLIJ_PLUGIN_DEBUG_TARGET("intellij_plugin_debug_target", LanguageClass.JAVA),
+ SCALA_BINARY("scala_binary", LanguageClass.SCALA),
+ SCALA_LIBRARY("scala_library", LanguageClass.SCALA),
+ SCALA_MACRO_LIBRARY("scala_macro_library", LanguageClass.SCALA),
+ SCALA_TEST("scala_test", LanguageClass.SCALA),
;
static final ImmutableMap<String, Kind> STRING_TO_KIND = makeStringToKindMap();
+ static final ImmutableMultimap<LanguageClass, Kind> PER_LANGUAGES_KINDS = makePerLanguageMap();
+
private static ImmutableMap<String, Kind> makeStringToKindMap() {
ImmutableMap.Builder<String, Kind> result = ImmutableMap.builder();
for (Kind kind : Kind.values()) {
@@ -69,10 +78,22 @@
return result.build();
}
+ private static ImmutableMultimap<LanguageClass, Kind> makePerLanguageMap() {
+ ImmutableMultimap.Builder<LanguageClass, Kind> result = ImmutableMultimap.builder();
+ for (Kind kind : Kind.values()) {
+ result.put(kind.languageClass, kind);
+ }
+ return result.build();
+ }
+
public static Kind fromString(String kindString) {
return STRING_TO_KIND.get(kindString);
}
+ public static ImmutableCollection<Kind> allKindsForLanguage(LanguageClass language) {
+ return PER_LANGUAGES_KINDS.get(language);
+ }
+
private final String kind;
private final LanguageClass languageClass;
@@ -94,7 +115,7 @@
return isOneOf(Arrays.asList(kinds));
}
- public boolean isOneOf(List<Kind> kinds) {
+ public boolean isOneOf(Collection<Kind> kinds) {
for (Kind kind : kinds) {
if (this.equals(kind)) {
return true;
diff --git a/base/src/com/google/idea/blaze/base/model/primitives/Label.java b/base/src/com/google/idea/blaze/base/model/primitives/Label.java
index c06f6a2..f86da52 100644
--- a/base/src/com/google/idea/blaze/base/model/primitives/Label.java
+++ b/base/src/com/google/idea/blaze/base/model/primitives/Label.java
@@ -23,7 +23,7 @@
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
-/** Wrapper around a string for a blaze label (//package:rule). */
+/** Wrapper around a string for a blaze label ([@external_workspace]//package:rule). */
@Immutable
public final class Label extends TargetExpression {
private static final Logger logger = Logger.getInstance(Label.class);
@@ -39,16 +39,31 @@
return null;
}
- public Label(String label) {
- super(label);
+ public static Label create(String label) {
List<BlazeValidationError> errors = Lists.newArrayList();
if (!validate(label, errors)) {
BlazeValidationError.throwError(errors);
}
+ return new Label(label);
}
- public Label(WorkspacePath packageName, TargetName newTargetName) {
- this("//" + packageName.toString() + ":" + newTargetName.toString());
+ public static Label create(WorkspacePath packageName, TargetName newTargetName) {
+ return create(null, packageName, newTargetName);
+ }
+
+ public static Label create(
+ @Nullable String externalWorkspaceName, WorkspacePath packagePath, TargetName targetName) {
+ String fullLabel =
+ String.format(
+ "%s//%s:%s",
+ externalWorkspaceName != null ? "@" + externalWorkspaceName : "",
+ packagePath,
+ targetName);
+ return new Label(fullLabel);
+ }
+
+ private Label(String label) {
+ super(label);
}
public static boolean validate(String label) {
@@ -81,6 +96,25 @@
return false;
}
+ public boolean isExternal() {
+ return toString().startsWith("@");
+ }
+
+ /**
+ * Returns the external workspace referenced by this label, or null if it's a main workspace
+ * label.
+ */
+ @Nullable
+ public String externalWorkspaceName() {
+ String label = toString();
+ if (!label.startsWith("@")) {
+ return null;
+ }
+ int slashesIndex = label.indexOf("//");
+ logger.assertTrue(slashesIndex >= 0);
+ return label.substring(1, slashesIndex);
+ }
+
/**
* Extract the target name from a label. The target name follows a colon at the end of the label.
*
@@ -106,7 +140,17 @@
return new WorkspacePath(labelStr.substring(startIndex, colonIndex));
}
- public static boolean validatePackagePath(String path) {
+ /** A new label with the same workspace and package paths, but a different target name. */
+ @Nullable
+ public Label withTargetName(@Nullable String targetName) {
+ if (targetName == null) {
+ return null;
+ }
+ TargetName target = TargetName.createIfValid(targetName);
+ return target != null ? Label.create(externalWorkspaceName(), blazePackage(), target) : null;
+ }
+
+ static boolean validatePackagePath(String path) {
return validatePackagePath(path, null);
}
diff --git a/base/src/com/google/idea/blaze/base/model/primitives/LanguageClass.java b/base/src/com/google/idea/blaze/base/model/primitives/LanguageClass.java
index cf030a2..e9cb3a8 100644
--- a/base/src/com/google/idea/blaze/base/model/primitives/LanguageClass.java
+++ b/base/src/com/google/idea/blaze/base/model/primitives/LanguageClass.java
@@ -29,7 +29,9 @@
TYPESCRIPT("typescript", ImmutableSet.of("ts", "ats")),
DART("dart", ImmutableSet.of("dart")),
GO("go", ImmutableSet.of("go")),
- PYTHON("python", ImmutableSet.of("py", "pyw"));
+ PYTHON("python", ImmutableSet.of("py", "pyw")),
+ SCALA("scala", ImmutableSet.of("scala")),
+ ;
private static final ImmutableMap<String, LanguageClass> RECOGNIZED_EXTENSIONS =
extensionToClassMap();
@@ -65,6 +67,11 @@
return null;
}
+ @Override
+ public String toString() {
+ return name;
+ }
+
/** Returns the LanguageClass associated with the given filename extension, if it's recognized. */
@Nullable
public static LanguageClass fromExtension(String filenameExtension) {
diff --git a/base/src/com/google/idea/blaze/base/model/primitives/TargetExpression.java b/base/src/com/google/idea/blaze/base/model/primitives/TargetExpression.java
index ea3d847..4e36aab 100644
--- a/base/src/com/google/idea/blaze/base/model/primitives/TargetExpression.java
+++ b/base/src/com/google/idea/blaze/base/model/primitives/TargetExpression.java
@@ -32,16 +32,21 @@
* it is not.
*/
public static TargetExpression fromString(String expression) {
- return Label.validate(expression) ? new Label(expression) : new TargetExpression(expression);
+ return Label.validate(expression) ? Label.create(expression) : new TargetExpression(expression);
}
- TargetExpression(String expression) {
+ protected TargetExpression(String expression) {
// TODO(joshgiles): Validation/canonicalization for target expressions.
// For reference, handled in Blaze/Bazel in TargetPattern.java.
Preconditions.checkArgument(!expression.isEmpty(), "Target should be non-empty.");
this.expression = expression;
}
+ /** Is this an excluded target expression (i.e. starts with '-')? */
+ public boolean isExcluded() {
+ return expression.startsWith("-");
+ }
+
@Override
public String toString() {
return expression;
@@ -63,8 +68,7 @@
/** All targets in all packages below the given path */
public static TargetExpression allFromPackageRecursive(WorkspacePath localPackage) {
- if (localPackage.relativePath().isEmpty()) {
- // localPackage is the workspace root
+ if (localPackage.isWorkspaceRoot()) {
return new TargetExpression("//...:all");
}
return new TargetExpression("//" + localPackage.relativePath() + "/...:all");
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/model/primitives/WorkspaceRoot.java b/base/src/com/google/idea/blaze/base/model/primitives/WorkspaceRoot.java
index b4a0a13..53d156d 100644
--- a/base/src/com/google/idea/blaze/base/model/primitives/WorkspaceRoot.java
+++ b/base/src/com/google/idea/blaze/base/model/primitives/WorkspaceRoot.java
@@ -108,7 +108,8 @@
private WorkspacePath workspacePathFor(String path) {
if (!isInWorkspace(path)) {
- throw new IllegalArgumentException("File is not under this workspace");
+ throw new IllegalArgumentException(
+ String.format("File '%s' is not under workspace %s", path, directory));
}
if (directory.getPath().length() == path.length()) {
return new WorkspacePath("");
diff --git a/base/src/com/google/idea/blaze/base/plugin/BlazeActionRemover.java b/base/src/com/google/idea/blaze/base/plugin/BlazeActionRemover.java
index 17e6043..c59731b 100644
--- a/base/src/com/google/idea/blaze/base/plugin/BlazeActionRemover.java
+++ b/base/src/com/google/idea/blaze/base/plugin/BlazeActionRemover.java
@@ -32,7 +32,7 @@
}
}
- private static void replaceAction(String actionId, AnAction newAction) {
+ public static void replaceAction(String actionId, AnAction newAction) {
ActionManager actionManager = ActionManager.getInstance();
AnAction oldAction = actionManager.getAction(actionId);
if (oldAction != null) {
diff --git a/base/src/com/google/idea/blaze/base/plugin/PluginUtils.java b/base/src/com/google/idea/blaze/base/plugin/PluginUtils.java
new file mode 100644
index 0000000..6156cbc
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/plugin/PluginUtils.java
@@ -0,0 +1,63 @@
+/*
+ * 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.plugin;
+
+import com.google.common.collect.ImmutableSet;
+import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.PluginManager;
+import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.PluginsAdvertiser;
+import com.intellij.openapi.util.EmptyRunnable;
+import com.intellij.pom.Navigatable;
+import com.intellij.pom.NavigatableAdapter;
+
+/** Utility methods for querying / manipulating other plugins. */
+public final class PluginUtils {
+
+ private PluginUtils() {}
+
+ /** If the plugin is already installed, enable it, otherwise both install and enable it. */
+ public static void installOrEnablePlugin(String pluginId) {
+ if (isPluginInstalled(pluginId)) {
+ PluginManager.enablePlugin(pluginId);
+ } else {
+ PluginsAdvertiser.installAndEnablePlugins(ImmutableSet.of(pluginId), EmptyRunnable.INSTANCE);
+ }
+ }
+
+ /** Returns a {@link Navigatable} which will install (if necessary) and enable the given plugin */
+ public static Navigatable installOrEnablePluginNavigable(String pluginId) {
+ return new NavigatableAdapter() {
+ @Override
+ public void navigate(boolean requestFocus) {
+ installOrEnablePlugin(pluginId);
+ }
+ };
+ }
+
+ public static boolean isPluginInstalled(String pluginId) {
+ return getPluginDescriptor(pluginId) != null;
+ }
+
+ public static boolean isPluginEnabled(String pluginId) {
+ IdeaPluginDescriptor descriptor = getPluginDescriptor(pluginId);
+ return descriptor != null && descriptor.isEnabled();
+ }
+
+ private static IdeaPluginDescriptor getPluginDescriptor(String pluginId) {
+ return PluginManager.getPlugin(PluginId.getId(pluginId));
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/prefetch/PrefetchFileSource.java b/base/src/com/google/idea/blaze/base/prefetch/PrefetchFileSource.java
index dcdc666..26c7491 100644
--- a/base/src/com/google/idea/blaze/base/prefetch/PrefetchFileSource.java
+++ b/base/src/com/google/idea/blaze/base/prefetch/PrefetchFileSource.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.prefetch;
import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
import java.io.File;
@@ -28,7 +29,10 @@
ExtensionPointName.create("com.google.idea.blaze.PrefetchFileSource");
/** Adds any files or directories that we would be interested in prefetching. */
void addFilesToPrefetch(
- Project project, BlazeProjectData blazeProjectData, Collection<File> files);
+ Project project,
+ ProjectViewSet projectViewSet,
+ BlazeProjectData blazeProjectData,
+ Collection<File> files);
/** Returns any source file extensions that are a good candidate for the {@link Prefetcher}. */
Set<String> prefetchSrcFileExtensions();
diff --git a/base/src/com/google/idea/blaze/base/prefetch/PrefetchProjectInitializer.java b/base/src/com/google/idea/blaze/base/prefetch/PrefetchProjectInitializer.java
new file mode 100644
index 0000000..ed7b4cc
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/prefetch/PrefetchProjectInitializer.java
@@ -0,0 +1,116 @@
+/*
+ * 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.prefetch;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.projectview.ProjectViewManager;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.settings.BlazeImportSettings;
+import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManagerImpl;
+import com.google.idea.common.experiments.BoolExperiment;
+import com.intellij.openapi.application.TransactionGuard;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.DumbModeTask;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.util.TimeoutUtil;
+import java.io.IOException;
+import javax.annotation.Nullable;
+
+/** Run prefetching on project open, prior to initial indexing step. */
+public class PrefetchProjectInitializer extends ApplicationComponent.Adapter {
+
+ private static final Logger logger = Logger.getInstance(PrefetchProjectInitializer.class);
+
+ private static final BoolExperiment prefetchOnProjectOpen =
+ new BoolExperiment("prefetch.on.project.open2", true);
+
+ @Override
+ public void initComponent() {
+ ProjectManager projectManager = ProjectManager.getInstance();
+ projectManager.addProjectManagerListener(
+ new ProjectManagerAdapter() {
+ @Override
+ public void projectOpened(Project project) {
+ if (prefetchOnProjectOpen.getValue()) {
+ prefetchProjectFiles(project);
+ }
+ }
+ });
+ }
+
+ private static void prefetchProjectFiles(Project project) {
+ BlazeProjectData projectData = getBlazeProjectData(project);
+ if (projectData == null) {
+ return;
+ }
+ ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
+ if (projectViewSet == null) {
+ return;
+ }
+ long start = System.currentTimeMillis();
+ ListenableFuture<?> future =
+ PrefetchService.getInstance().prefetchProjectFiles(project, projectViewSet, projectData);
+ TransactionGuard.submitTransaction(
+ project,
+ () -> {
+ DumbService.getInstance(project).queueTask(new PrefetchTask(future, start));
+ });
+ }
+
+ static class PrefetchTask extends DumbModeTask {
+ private final ListenableFuture<?> future;
+ private final long startTimeMillis;
+
+ private PrefetchTask(ListenableFuture<?> future, long startTimeMillis) {
+ this.future = future;
+ this.startTimeMillis = startTimeMillis;
+ }
+
+ @Override
+ public void performInDumbMode(ProgressIndicator indicator) {
+ indicator.setIndeterminate(true);
+ indicator.setText("Prefetching files...");
+ while (!future.isCancelled() && !future.isDone()) {
+ indicator.checkCanceled();
+ TimeoutUtil.sleep(100);
+ }
+ long end = System.currentTimeMillis();
+ logger.info(String.format("Initial prefetching took: %d ms", (end - startTimeMillis)));
+ }
+ }
+
+ @Nullable
+ private static BlazeProjectData getBlazeProjectData(Project project) {
+ BlazeImportSettings importSettings =
+ BlazeImportSettingsManager.getInstance(project).getImportSettings();
+ if (importSettings == null) {
+ return null;
+ }
+ try {
+ return BlazeProjectDataManagerImpl.getImpl(project).loadProjectRoot(importSettings);
+ } catch (IOException e) {
+ // ignore: if we can't load the previous project data, we don't know what to prefetch
+ return null;
+ }
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/prefetch/PrefetchService.java b/base/src/com/google/idea/blaze/base/prefetch/PrefetchService.java
index fc5f5e2..726f970 100644
--- a/base/src/com/google/idea/blaze/base/prefetch/PrefetchService.java
+++ b/base/src/com/google/idea/blaze/base/prefetch/PrefetchService.java
@@ -17,6 +17,7 @@
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import java.io.File;
@@ -31,5 +32,6 @@
/** Instructs all prefetchers to prefetch these files. */
ListenableFuture<?> prefetchFiles(Project project, Collection<File> files);
- ListenableFuture<?> prefetchProjectFiles(Project project, BlazeProjectData blazeProjectData);
+ ListenableFuture<?> prefetchProjectFiles(
+ Project project, ProjectViewSet projectViewSet, BlazeProjectData blazeProjectData);
}
diff --git a/base/src/com/google/idea/blaze/base/prefetch/PrefetchServiceImpl.java b/base/src/com/google/idea/blaze/base/prefetch/PrefetchServiceImpl.java
index 8046db0..05e02a6 100644
--- a/base/src/com/google/idea/blaze/base/prefetch/PrefetchServiceImpl.java
+++ b/base/src/com/google/idea/blaze/base/prefetch/PrefetchServiceImpl.java
@@ -22,7 +22,6 @@
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;
-import com.google.idea.blaze.base.projectview.ProjectViewManager;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
@@ -47,11 +46,7 @@
@Override
public ListenableFuture<?> prefetchProjectFiles(
- Project project, BlazeProjectData blazeProjectData) {
- ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
- if (projectViewSet == null) {
- return Futures.immediateFuture(null);
- }
+ Project project, ProjectViewSet projectViewSet, BlazeProjectData blazeProjectData) {
BlazeImportSettings importSettings =
BlazeImportSettingsManager.getInstance(project).getImportSettings();
if (importSettings == null) {
@@ -68,7 +63,7 @@
files.add(workspaceRoot.fileForPath(workspacePath));
}
for (PrefetchFileSource fileSource : PrefetchFileSource.EP_NAME.getExtensions()) {
- fileSource.addFilesToPrefetch(project, blazeProjectData, files);
+ fileSource.addFilesToPrefetch(project, projectViewSet, blazeProjectData, files);
}
return prefetchFiles(project, files);
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/ProjectView.java b/base/src/com/google/idea/blaze/base/projectview/ProjectView.java
index 8dfc6f3..4d09c18 100644
--- a/base/src/com/google/idea/blaze/base/projectview/ProjectView.java
+++ b/base/src/com/google/idea/blaze/base/projectview/ProjectView.java
@@ -17,11 +17,15 @@
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+import com.google.idea.blaze.base.projectview.section.ListSection;
+import com.google.idea.blaze.base.projectview.section.ScalarSection;
import com.google.idea.blaze.base.projectview.section.Section;
import com.google.idea.blaze.base.projectview.section.SectionBuilder;
import com.google.idea.blaze.base.projectview.section.SectionKey;
import java.io.Serializable;
+import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
@@ -47,6 +51,32 @@
return result.build();
}
+ /** Returns all values from the given list section */
+ public <T> List<T> listItems(SectionKey<T, ListSection<T>> key) {
+ List<T> result = Lists.newArrayList();
+ for (ListSection<T> section : getSectionsOfType(key)) {
+ result.addAll(section.items());
+ }
+ return result;
+ }
+
+ /** Gets the last value from any scalar sections */
+ @Nullable
+ public <T> T getScalarValue(SectionKey<T, ScalarSection<T>> key) {
+ return getScalarValue(key, null);
+ }
+
+ /** Gets the last value from any scalar sections */
+ @Nullable
+ public <T> T getScalarValue(SectionKey<T, ScalarSection<T>> key, @Nullable T defaultValue) {
+ Collection<ScalarSection<T>> sections = getSectionsOfType(key);
+ if (sections.isEmpty()) {
+ return defaultValue;
+ } else {
+ return Iterables.getLast(sections).getValue();
+ }
+ }
+
public static Builder builder() {
return new Builder();
}
@@ -107,6 +137,11 @@
return this;
}
+ public <T> Builder remove(Section<T> section) {
+ sections.remove(section);
+ return this;
+ }
+
/** Replaces a section if it already exists. If it doesn't, just add the section. */
public <T, SectionType extends Section<T>> Builder replace(
@Nullable Section<T> section, SectionBuilder<T, SectionType> builder) {
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/ProjectViewSet.java b/base/src/com/google/idea/blaze/base/projectview/ProjectViewSet.java
index 1f3ed1f..e2e1211 100644
--- a/base/src/com/google/idea/blaze/base/projectview/ProjectViewSet.java
+++ b/base/src/com/google/idea/blaze/base/projectview/ProjectViewSet.java
@@ -63,7 +63,8 @@
}
/** Gets the last value from any scalar sections */
- public <T> T getScalarValue(SectionKey<T, ScalarSection<T>> key, T defaultValue) {
+ @Nullable
+ public <T> T getScalarValue(SectionKey<T, ScalarSection<T>> key, @Nullable T defaultValue) {
Collection<ScalarSection<T>> sections = getSections(key);
if (sections.isEmpty()) {
return defaultValue;
@@ -82,7 +83,7 @@
return result;
}
- public Collection<ProjectViewFile> getProjectViewFiles() {
+ public ImmutableList<ProjectViewFile> getProjectViewFiles() {
return projectViewFiles;
}
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/ProjectViewVerifier.java b/base/src/com/google/idea/blaze/base/projectview/ProjectViewVerifier.java
index 9b4b465..1d35932 100644
--- a/base/src/com/google/idea/blaze/base/projectview/ProjectViewVerifier.java
+++ b/base/src/com/google/idea/blaze/base/projectview/ProjectViewVerifier.java
@@ -29,11 +29,14 @@
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.sync.BlazeSyncPlugin;
+import com.google.idea.blaze.base.sync.projectview.LanguageSupport;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import java.io.File;
import java.util.List;
+import javax.annotation.Nullable;
/** Verifies project views. */
public class ProjectViewVerifier {
@@ -48,6 +51,7 @@
/** Verifies the project view. Any errors are output to the context as issues. */
public static boolean verifyProjectView(
+ @Nullable Project project,
BlazeContext context,
WorkspacePathResolver workspacePathResolver,
ProjectViewSet projectViewSet,
@@ -56,10 +60,14 @@
return false;
}
for (BlazeSyncPlugin syncPlugin : BlazeSyncPlugin.EP_NAME.getExtensions()) {
- if (!syncPlugin.validateProjectView(context, projectViewSet, workspaceLanguageSettings)) {
+ if (!syncPlugin.validateProjectView(
+ project, context, projectViewSet, workspaceLanguageSettings)) {
return false;
}
}
+ if (!LanguageSupport.validateLanguageSettings(context, workspaceLanguageSettings)) {
+ return false;
+ }
warnAboutDeprecatedSections(context, projectViewSet);
if (!verifyIncludedPackagesExistOnDisk(context, workspacePathResolver, projectViewSet)) {
return false;
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..6956bbb 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
@@ -15,6 +15,7 @@
*/
package com.google.idea.blaze.base.projectview.parser;
+import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.IssueOutput;
@@ -22,7 +23,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 {
@@ -55,7 +56,7 @@
this.context = context;
this.workspacePathResolver = workspacePathResolver;
this.file = file;
- this.lines = Lists.newArrayList(text.split("\n"));
+ this.lines = Lists.newArrayList(Splitter.on('\n').split(text));
this.currentLine = null;
this.currentLineIndex = -1;
consume();
diff --git a/base/src/com/google/idea/blaze/base/projectview/parser/ProjectViewParser.java b/base/src/com/google/idea/blaze/base/projectview/parser/ProjectViewParser.java
index 2f4707f..5349ec2 100644
--- a/base/src/com/google/idea/blaze/base/projectview/parser/ProjectViewParser.java
+++ b/base/src/com/google/idea/blaze/base/projectview/parser/ProjectViewParser.java
@@ -68,6 +68,11 @@
}
public void parseProjectView(String text) {
+ if (text.isEmpty()) {
+ ProjectView projectView = new ProjectView(ImmutableList.of());
+ projectViewFiles.add(new ProjectViewSet.ProjectViewFile(projectView, null));
+ return;
+ }
parseProjectView(new ParseContext(context, workspacePathResolver, null, text));
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/LabelSectionParser.java b/base/src/com/google/idea/blaze/base/projectview/section/LabelSectionParser.java
index bc1ed4a..9c7aafc 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/LabelSectionParser.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/LabelSectionParser.java
@@ -38,7 +38,7 @@
parseContext.addErrors(errors);
return null;
}
- return new Label(text);
+ return Label.create(text);
}
@Override
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/ListSection.java b/base/src/com/google/idea/blaze/base/projectview/section/ListSection.java
index 40ec7da..d3d9e06 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/ListSection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/ListSection.java
@@ -19,7 +19,9 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.projectview.section.sections.ItemOrTextBlock;
import com.google.idea.blaze.base.projectview.section.sections.TextBlock;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
@@ -82,7 +84,7 @@
/** Builder for list sections */
public static class Builder<T> extends SectionBuilder<T, ListSection<T>> {
- private final ImmutableList.Builder<ItemOrTextBlock<T>> items = ImmutableList.builder();
+ private final List<ItemOrTextBlock<T>> items = new ArrayList<>();
public Builder(SectionKey<T, ListSection<T>> sectionKey, @Nullable ListSection<T> section) {
super(sectionKey);
@@ -96,14 +98,26 @@
return this;
}
+ public final Builder<T> addAll(List<T> items) {
+ for (T item : items) {
+ add(item);
+ }
+ return this;
+ }
+
public final Builder<T> add(TextBlock textBlock) {
items.add(new ItemOrTextBlock<T>(textBlock));
return this;
}
+ public final Builder<T> remove(T item) {
+ items.remove(new ItemOrTextBlock<>(item));
+ return this;
+ }
+
@Override
public final ListSection<T> build() {
- return new ListSection<>(getSectionKey(), items.build());
+ return new ListSection<>(getSectionKey(), ImmutableList.copyOf(items));
}
}
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/ProjectViewDefaultValueProvider.java b/base/src/com/google/idea/blaze/base/projectview/section/ProjectViewDefaultValueProvider.java
new file mode 100644
index 0000000..370295f
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/projectview/section/ProjectViewDefaultValueProvider.java
@@ -0,0 +1,32 @@
+/*
+ * 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.projectview.section;
+
+import com.google.idea.blaze.base.projectview.ProjectView;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+/** Allows the adding default values to sections. Used during the wizard. */
+public interface ProjectViewDefaultValueProvider {
+ ExtensionPointName<ProjectViewDefaultValueProvider> EP_NAME =
+ ExtensionPointName.create("com.google.idea.blaze.ProjectViewDefaultValueProvider");
+
+ ProjectView addProjectViewDefaultValue(
+ BuildSystem buildSystem, ProjectViewSet projectViewSet, ProjectView topLevelProjectView);
+
+ SectionKey<?, ?> getSectionKey();
+}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/SectionParser.java b/base/src/com/google/idea/blaze/base/projectview/section/SectionParser.java
index 1e0f043..2c76bb6 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/SectionParser.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/SectionParser.java
@@ -15,7 +15,6 @@
*/
package com.google.idea.blaze.base.projectview.section;
-import com.google.idea.blaze.base.projectview.ProjectView;
import com.google.idea.blaze.base.projectview.parser.ParseContext;
import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
import javax.annotation.Nullable;
@@ -52,9 +51,10 @@
return null;
}
- /** Allows the section to add a default value. Used during the wizard. */
- public ProjectView addProjectViewDefaultValue(ProjectView projectView) {
- return projectView;
+ /** A brief description of this section, used for in-IDE documentation. */
+ @Nullable
+ public String quickDocs() {
+ return null;
}
/** The type of item(s) in this section. */
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/AdditionalLanguagesSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/AdditionalLanguagesSection.java
index d9dc894..9e05e64 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/AdditionalLanguagesSection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/AdditionalLanguagesSection.java
@@ -15,13 +15,21 @@
*/
package com.google.idea.blaze.base.projectview.section.sections;
+import com.google.common.collect.Ordering;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
+import com.google.idea.blaze.base.model.primitives.WorkspaceType;
+import com.google.idea.blaze.base.projectview.ProjectView;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.parser.ParseContext;
import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
import com.google.idea.blaze.base.projectview.section.ListSection;
import com.google.idea.blaze.base.projectview.section.ListSectionParser;
+import com.google.idea.blaze.base.projectview.section.ProjectViewDefaultValueProvider;
import com.google.idea.blaze.base.projectview.section.SectionKey;
import com.google.idea.blaze.base.projectview.section.SectionParser;
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
+import com.google.idea.blaze.base.sync.projectview.LanguageSupport;
+import java.util.Set;
import javax.annotation.Nullable;
/** Allows users to set the rule classes they want to be imported */
@@ -56,5 +64,45 @@
public ItemType getItemType() {
return ItemType.Other;
}
+
+ @Override
+ public String quickDocs() {
+ return "Additional languages to support in this project.";
+ }
+ }
+
+ static class AdditionalLanguagesDefaultValueProvider implements ProjectViewDefaultValueProvider {
+ @Override
+ public ProjectView addProjectViewDefaultValue(
+ BuildSystem buildSystem, ProjectViewSet projectViewSet, ProjectView topLevelProjectView) {
+ if (!topLevelProjectView.getSectionsOfType(KEY).isEmpty()) {
+ return topLevelProjectView;
+ }
+ Set<LanguageClass> additionalLanguages = availableAdditionalLanguages(projectViewSet);
+ if (additionalLanguages.isEmpty()) {
+ return topLevelProjectView;
+ }
+ ListSection.Builder<LanguageClass> builder = ListSection.builder(KEY);
+ builder.add(TextBlock.of(" # Uncomment any additional languages you want supported"));
+ additionalLanguages
+ .stream()
+ .sorted(Ordering.usingToString())
+ .map(lang -> " # " + lang.getName())
+ .forEach(string -> builder.add(TextBlock.of(string)));
+ builder.add(TextBlock.newLine());
+ return ProjectView.builder(topLevelProjectView).add(builder).build();
+ }
+
+ @Override
+ public SectionKey<?, ?> getSectionKey() {
+ return KEY;
+ }
+
+ private static Set<LanguageClass> availableAdditionalLanguages(ProjectViewSet projectView) {
+ WorkspaceType workspaceType =
+ projectView.getScalarValue(
+ WorkspaceTypeSection.KEY, LanguageSupport.getDefaultWorkspaceType());
+ return LanguageSupport.availableAdditionalLanguages(workspaceType);
+ }
}
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/BuildFlagsSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/BuildFlagsSection.java
index 588d289..51f0709 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/BuildFlagsSection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/BuildFlagsSection.java
@@ -48,5 +48,10 @@
public ItemType getItemType() {
return ItemType.Other;
}
+
+ @Override
+ public String quickDocs() {
+ return "A set of flags that get passed to all build command invocations as arguments";
+ }
}
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/DirectorySection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/DirectorySection.java
index cc1cb23..c470e37 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/DirectorySection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/DirectorySection.java
@@ -18,12 +18,15 @@
import com.google.common.collect.Lists;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.projectview.ProjectView;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.parser.ParseContext;
import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
import com.google.idea.blaze.base.projectview.section.ListSection;
import com.google.idea.blaze.base.projectview.section.ListSectionParser;
+import com.google.idea.blaze.base.projectview.section.ProjectViewDefaultValueProvider;
import com.google.idea.blaze.base.projectview.section.SectionKey;
import com.google.idea.blaze.base.projectview.section.SectionParser;
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.ui.BlazeValidationError;
import com.intellij.util.PathUtil;
import java.util.List;
@@ -69,16 +72,32 @@
}
@Override
- public ProjectView addProjectViewDefaultValue(ProjectView projectView) {
- if (!projectView.getSectionsOfType(KEY).isEmpty()) {
- return projectView;
+ public String quickDocs() {
+ return "A list of project directories that will be added as source.";
+ }
+ }
+
+ static class DirectoriesProjectViewDefaultValueProvider
+ implements ProjectViewDefaultValueProvider {
+ @Override
+ public ProjectView addProjectViewDefaultValue(
+ BuildSystem buildSystem, ProjectViewSet projectViewSet, ProjectView topLevelProjectView) {
+ if (!topLevelProjectView.getSectionsOfType(KEY).isEmpty()) {
+ return topLevelProjectView;
}
- return ProjectView.builder(projectView)
- .add(
- ListSection.builder(KEY)
- .add(TextBlock.of(" # Add the directories you want added as source here"))
- .add(TextBlock.newLine()))
- .build();
+ ListSection.Builder<DirectoryEntry> builder = ListSection.builder(KEY);
+ builder.add(TextBlock.of(" # Add the directories you want added as source here"));
+ if (buildSystem == BuildSystem.Bazel) {
+ builder.add(TextBlock.of(" # By default, we've added your entire workspace ('.')"));
+ builder.add(DirectoryEntry.include(new WorkspacePath(".")));
+ }
+ builder.add(TextBlock.newLine());
+ return ProjectView.builder(topLevelProjectView).add(builder).build();
+ }
+
+ @Override
+ public SectionKey<?, ?> getSectionKey() {
+ return KEY;
}
}
}
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..d054235 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 {
@@ -70,5 +70,10 @@
public ItemType getItemType() {
return ItemType.FileSystemItem;
}
+
+ @Override
+ public String quickDocs() {
+ return "Imports another project view.";
+ }
}
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/RunConfigurationsSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/RunConfigurationsSection.java
index 9ffda84..c3a8ef6 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/RunConfigurationsSection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/RunConfigurationsSection.java
@@ -59,5 +59,10 @@
public ItemType getItemType() {
return ItemType.FileSystemItem;
}
+
+ @Override
+ public String quickDocs() {
+ return "A list of XML files which will be imported as run configurations during sync.";
+ }
}
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/Sections.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/Sections.java
index 4d071a3..eda173f 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/Sections.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/Sections.java
@@ -36,7 +36,8 @@
ImportTargetOutputSection.PARSER,
ExcludeTargetSection.PARSER,
ExcludedSourceSection.PARSER,
- RunConfigurationsSection.PARSER);
+ RunConfigurationsSection.PARSER,
+ ShardBlazeBuildsSection.PARSER);
public static List<SectionParser> getParsers() {
List<SectionParser> parsers = Lists.newArrayList(PARSERS);
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/ShardBlazeBuildsSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/ShardBlazeBuildsSection.java
new file mode 100644
index 0000000..0b75c8b
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/ShardBlazeBuildsSection.java
@@ -0,0 +1,65 @@
+/*
+ * 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.projectview.section.sections;
+
+import com.google.idea.blaze.base.projectview.parser.ParseContext;
+import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
+import com.google.idea.blaze.base.projectview.section.ScalarSection;
+import com.google.idea.blaze.base.projectview.section.ScalarSectionParser;
+import com.google.idea.blaze.base.projectview.section.SectionKey;
+import com.google.idea.blaze.base.projectview.section.SectionParser;
+import javax.annotation.Nullable;
+
+/** Set for particularly large projects to enable sharding blaze invocations during blaze sync. */
+public class ShardBlazeBuildsSection {
+ public static final SectionKey<Boolean, ScalarSection<Boolean>> KEY = SectionKey.of("shard_sync");
+ public static final SectionParser PARSER = new ShardBlazeSyncSectionParser();
+
+ private static class ShardBlazeSyncSectionParser extends ScalarSectionParser<Boolean> {
+ ShardBlazeSyncSectionParser() {
+ super(KEY, ':');
+ }
+
+ @Override
+ @Nullable
+ protected Boolean parseItem(ProjectViewParser parser, ParseContext parseContext, String text) {
+ if (text.equals("true")) {
+ return true;
+ }
+ if (text.equals("false")) {
+ return false;
+ }
+ parseContext.addError(
+ "'shard_sync' must be set to 'true' or 'false' (e.g. 'shard_sync: true')");
+ return null;
+ }
+
+ @Override
+ protected void printItem(StringBuilder sb, Boolean item) {
+ sb.append(item);
+ }
+
+ @Override
+ public ItemType getItemType() {
+ return ItemType.Other;
+ }
+
+ @Override
+ public String quickDocs() {
+ return "Allows sharding build invocations when syncing and compiling your project.";
+ }
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/TargetSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/TargetSection.java
index cd69179..01e38c6 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/TargetSection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/TargetSection.java
@@ -17,12 +17,16 @@
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.projectview.ProjectView;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.parser.ParseContext;
import com.google.idea.blaze.base.projectview.parser.ProjectViewParser;
import com.google.idea.blaze.base.projectview.section.ListSection;
import com.google.idea.blaze.base.projectview.section.ListSectionParser;
+import com.google.idea.blaze.base.projectview.section.ProjectViewDefaultValueProvider;
import com.google.idea.blaze.base.projectview.section.SectionKey;
import com.google.idea.blaze.base.projectview.section.SectionParser;
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
+import javax.annotation.Nullable;
/** "targets" section. */
public class TargetSection {
@@ -51,20 +55,35 @@
return ItemType.Label;
}
+ @Nullable
@Override
- public ProjectView addProjectViewDefaultValue(ProjectView projectView) {
- if (!projectView.getSectionsOfType(KEY).isEmpty()) {
- return projectView;
+ public String quickDocs() {
+ return "A list of build targets that will be included during sync. To resolve source files "
+ + "under a project directory, the source must be reachable from one of your targets.";
+ }
+ }
+
+ static class TargetsProjectViewDefaultValueProvider implements ProjectViewDefaultValueProvider {
+ @Override
+ public ProjectView addProjectViewDefaultValue(
+ BuildSystem buildSystem, ProjectViewSet projectViewSet, ProjectView topLevelProjectView) {
+ if (!topLevelProjectView.getSectionsOfType(KEY).isEmpty()) {
+ return topLevelProjectView;
}
- return ProjectView.builder(projectView)
- .add(
- ListSection.builder(KEY)
- .add(
- TextBlock.of(
- " # Add targets that reach the source code "
- + "that you want to resolve here"))
- .add(TextBlock.newLine()))
- .build();
+ ListSection.Builder<TargetExpression> builder = ListSection.builder(KEY);
+ builder.add(
+ TextBlock.of(" # Add targets that reach the source code that you want to resolve here"));
+ if (buildSystem == BuildSystem.Bazel) {
+ builder.add(TextBlock.of(" # By default, we've added all targets in your workspace"));
+ builder.add(TargetExpression.fromString("//..."));
+ }
+ builder.add(TextBlock.newLine());
+ return ProjectView.builder(topLevelProjectView).add(builder).build();
+ }
+
+ @Override
+ public SectionKey<?, ?> getSectionKey() {
+ return KEY;
}
}
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/TestSourceSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/TestSourceSection.java
index 44da7b0..309b765 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/TestSourceSection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/TestSourceSection.java
@@ -24,5 +24,12 @@
/** Section for configuring test sources. */
public class TestSourceSection {
public static final SectionKey<Glob, ListSection<Glob>> KEY = SectionKey.of("test_sources");
- public static final SectionParser PARSER = new GlobSectionParser(KEY);
+ public static final SectionParser PARSER =
+ new GlobSectionParser(KEY) {
+ @Override
+ public String quickDocs() {
+ return "A list of workspace-relative glob patterns. Determines which sources IntelliJ "
+ + "treats as test sources.";
+ }
+ };
}
diff --git a/base/src/com/google/idea/blaze/base/projectview/section/sections/TextBlockSection.java b/base/src/com/google/idea/blaze/base/projectview/section/sections/TextBlockSection.java
index b12b781..1631179 100644
--- a/base/src/com/google/idea/blaze/base/projectview/section/sections/TextBlockSection.java
+++ b/base/src/com/google/idea/blaze/base/projectview/section/sections/TextBlockSection.java
@@ -137,5 +137,11 @@
public ItemType getItemType() {
return ItemType.Other;
}
+
+ @Nullable
+ @Override
+ public String quickDocs() {
+ return null;
+ }
}
}
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..96be88d 100644
--- a/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationSyncListener.java
+++ b/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationSyncListener.java
@@ -34,6 +34,7 @@
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.project.Project;
import java.io.File;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -67,7 +68,7 @@
Set<Label> labelsWithConfigs = labelsWithConfigs(project);
Set<TargetExpression> targetExpressions =
- Sets.newHashSet(projectViewSet.listItems(TargetSection.KEY));
+ Sets.newLinkedHashSet(projectViewSet.listItems(TargetSection.KEY));
// We only auto-generate configurations for rules listed in the project view.
for (TargetExpression target : targetExpressions) {
if (!(target instanceof Label) || labelsWithConfigs.contains(target)) {
@@ -86,7 +87,7 @@
.listItems(RunConfigurationsSection.KEY)
.stream()
.map(pathResolver::resolveToFile)
- .collect(Collectors.toSet());
+ .collect(Collectors.toCollection(LinkedHashSet::new));
}
/** Collects a set of all the Blaze labels that have an associated run configuration. */
@@ -119,7 +120,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..bf3cd6c 100644
--- a/base/src/com/google/idea/blaze/base/run/TargetNameHeuristic.java
+++ b/base/src/com/google/idea/blaze/base/run/TargetNameHeuristic.java
@@ -17,7 +17,9 @@
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 com.intellij.psi.PsiFile;
import java.io.File;
import javax.annotation.Nullable;
@@ -25,7 +27,12 @@
public class TargetNameHeuristic implements TestTargetHeuristic {
@Override
- public boolean matchesSource(TargetIdeInfo target, File sourceFile, @Nullable TestSize testSize) {
+ public boolean matchesSource(
+ Project project,
+ TargetIdeInfo target,
+ @Nullable PsiFile sourcePsiFile,
+ 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..c30a55e 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,8 @@
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 com.intellij.psi.PsiFile;
import java.io.File;
import javax.annotation.Nullable;
@@ -25,7 +27,12 @@
public class TestSizeHeuristic implements TestTargetHeuristic {
@Override
- public boolean matchesSource(TargetIdeInfo target, File sourceFile, @Nullable TestSize testSize) {
+ public boolean matchesSource(
+ Project project,
+ TargetIdeInfo target,
+ @Nullable PsiFile sourcePsiFile,
+ 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..74a46e4 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;
@@ -38,22 +39,18 @@
if (element == null) {
return null;
}
- File file = getContainingFile(element);
- if (file == null) {
- return null;
- }
- Collection<TargetIdeInfo> rules =
- TestTargetFinder.getInstance(element.getProject()).testTargetsForSourceFile(file);
- return chooseTestTargetForSourceFile(file, rules, null);
- }
-
- static File getContainingFile(PsiElement element) {
PsiFile psiFile = element.getContainingFile();
if (psiFile == null) {
return null;
}
VirtualFile vf = psiFile.getVirtualFile();
- return vf != null ? new File(vf.getPath()) : null;
+ File file = vf != null ? new File(vf.getPath()) : null;
+ if (file == null) {
+ return null;
+ }
+ Collection<TargetIdeInfo> rules =
+ TestTargetFinder.getInstance(element.getProject()).testTargetsForSourceFile(file);
+ return chooseTestTargetForSourceFile(element.getProject(), psiFile, file, rules, null);
}
/**
@@ -62,13 +59,19 @@
*/
@Nullable
static Label chooseTestTargetForSourceFile(
- File sourceFile, Collection<TargetIdeInfo> targets, @Nullable TestIdeInfo.TestSize testSize) {
+ Project project,
+ @Nullable PsiFile sourcePsiFile,
+ 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, sourcePsiFile, sourceFile, testSize))
.findFirst()
.orElse(null);
@@ -81,5 +84,9 @@
/** 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,
+ @Nullable PsiFile sourcePsiFile,
+ 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..9a9fb9f
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/TestTargetSourcesHeuristic.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.intellij.psi.PsiFile;
+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,
+ @Nullable PsiFile sourcePsiFile,
+ 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/WithBrowserHyperlinkExecutionException.java b/base/src/com/google/idea/blaze/base/run/WithBrowserHyperlinkExecutionException.java
new file mode 100644
index 0000000..16b9c23
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/WithBrowserHyperlinkExecutionException.java
@@ -0,0 +1,49 @@
+/*
+ * 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.intellij.execution.ExecutionException;
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationListener;
+import com.intellij.ui.BrowserHyperlinkListener;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * An {@link ExecutionException} containing a clickable browser hyperlink. It attempts to navigate
+ * to a URL formed from the hyperlink description verbatim.
+ */
+public class WithBrowserHyperlinkExecutionException extends ExecutionException
+ implements HyperlinkListener, NotificationListener {
+
+ public WithBrowserHyperlinkExecutionException(String string) {
+ super(string);
+ }
+
+ @Override
+ public final void hyperlinkUpdate(HyperlinkEvent e) {
+ if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
+ BrowserHyperlinkListener.INSTANCE.hyperlinkUpdate(e);
+ }
+ }
+
+ @Override
+ public final void hyperlinkUpdate(
+ @NotNull Notification notification, @NotNull HyperlinkEvent event) {
+ hyperlinkUpdate(event);
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationHandler.java b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationHandler.java
index da3d641..6d8dcd7 100644
--- a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationHandler.java
+++ b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationHandler.java
@@ -72,7 +72,7 @@
@Override
@Nullable
public String getCommandName() {
- BlazeCommandName command = state.getCommand();
+ BlazeCommandName command = state.getCommandState().getCommand();
return command != null ? command.toString() : null;
}
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..4605c17 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,29 +165,28 @@
ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
assert projectViewSet != null;
+ String binaryPath =
+ handlerState.getBlazeBinaryState().getBlazeBinary() != null
+ ? handlerState.getBlazeBinaryState().getBlazeBinary()
+ : Blaze.getBuildSystemProvider(project).getBinaryPath();
+
BlazeCommand.Builder command =
- BlazeCommand.builder(Blaze.getBuildSystem(project), handlerState.getCommand())
- .setBlazeBinary(handlerState.getBlazeBinary())
+ BlazeCommand.builder(binaryPath, handlerState.getCommandState().getCommand())
.addTargets(configuration.getTarget())
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
.addBlazeFlags(testHandlerFlags)
- .addBlazeFlags(handlerState.getBlazeFlags())
- .addExeFlags(handlerState.getExeFlags());
+ .addBlazeFlags(handlerState.getBlazeFlagsState().getExpandedFlags())
+ .addExeFlags(handlerState.getExeFlagsState().getExpandedFlags());
- boolean runDistributed = handlerState.getRunOnDistributedExecutor();
command.addBlazeFlags(
DistributedExecutorSupport.getBlazeFlags(
- project, handlerState.getRunOnDistributedExecutor()));
- if (!runDistributed) {
- command.addBlazeFlags(BlazeFlags.TEST_OUTPUT_STREAMED);
- }
+ project, handlerState.getRunOnDistributedExecutorState().runOnDistributedExecutor));
return command.build();
}
private boolean canUseTestUi() {
- return smRunnerUiEnabled.getValue()
- && BlazeCommandName.TEST.equals(handlerState.getCommand())
- && !handlerState.getRunOnDistributedExecutor();
+ return BlazeCommandName.TEST.equals(handlerState.getCommandState().getCommand())
+ && !handlerState.getRunOnDistributedExecutorState().runOnDistributedExecutor;
}
}
}
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..2e4f9ea 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
@@ -15,6 +15,7 @@
*/
package com.google.idea.blaze.base.run.filter;
+import com.google.common.annotations.VisibleForTesting;
import com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager;
import com.google.idea.blaze.base.lang.buildfile.references.LabelUtils;
import com.google.idea.blaze.base.model.primitives.Label;
@@ -23,14 +24,24 @@
import com.intellij.openapi.project.Project;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.PsiElement;
+import java.util.ArrayList;
+import java.util.List;
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 {
- private static final Pattern TARGET_PATTERN = Pattern.compile("//([^\\s:]*):(\\S*)");
+ // See Bazel's LabelValidator class. Whitespace character intentionally not included here.
+ private static final String PACKAGE_NAME_CHARS = "a-zA-Z0-9/\\-\\._$()";
+ private static final String TARGET_CHARS = "a-zA-Z0-9+,=~#()$_@\\-";
+
+ private static final String TARGET_REGEX =
+ String.format(
+ "(@[%s]*)?//[%s]*(:[%s]*)?", PACKAGE_NAME_CHARS, PACKAGE_NAME_CHARS, TARGET_CHARS);
+
+ @VisibleForTesting static final Pattern TARGET_PATTERN = Pattern.compile(TARGET_REGEX);
private final Project project;
@@ -42,20 +53,21 @@
@Override
public Result applyFilter(String line, int entireLength) {
Matcher matcher = TARGET_PATTERN.matcher(line);
- if (!matcher.find()) {
- return null;
+ List<ResultItem> results = new ArrayList<>();
+ while (matcher.find()) {
+ String labelString = matcher.group();
+ Label label = LabelUtils.createLabelFromString(null, labelString);
+ if (label == null) {
+ continue;
+ }
+ PsiElement psi = BuildReferenceManager.getInstance(project).resolveLabel(label);
+ if (!(psi instanceof NavigatablePsiElement)) {
+ continue;
+ }
+ HyperlinkInfo link = project -> ((NavigatablePsiElement) psi).navigate(true);
+ int offset = entireLength - line.length();
+ results.add(new ResultItem(matcher.start() + offset, matcher.end() + offset, link));
}
- String labelString = matcher.group();
- Label label = LabelUtils.createLabelFromString(null, labelString);
- if (label == null) {
- return null;
- }
- PsiElement psi = BuildReferenceManager.getInstance(project).resolveLabel(label);
- if (!(psi instanceof NavigatablePsiElement)) {
- return null;
- }
- HyperlinkInfo link = project -> ((NavigatablePsiElement) psi).navigate(true);
- int offset = entireLength - line.length();
- return new Result(matcher.start() + offset, matcher.end() + offset, link);
+ return results.isEmpty() ? null : new Result(results);
}
}
diff --git a/base/src/com/google/idea/blaze/base/run/filter/StandardFileResolver.java b/base/src/com/google/idea/blaze/base/run/filter/StandardFileResolver.java
index 15a3d09..652c2a5 100644
--- a/base/src/com/google/idea/blaze/base/run/filter/StandardFileResolver.java
+++ b/base/src/com/google/idea/blaze/base/run/filter/StandardFileResolver.java
@@ -21,6 +21,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import java.io.File;
+import java.io.IOException;
import javax.annotation.Nullable;
/** Parses absolute and workspace-relative paths. */
@@ -31,7 +32,9 @@
public VirtualFile resolveToFile(Project project, String fileString) {
File file = new File(fileString);
if (file.isAbsolute()) {
- return VirtualFileSystemProvider.getInstance().getSystem().findFileByPath(file.getPath());
+ return VirtualFileSystemProvider.getInstance()
+ .getSystem()
+ .findFileByPath(getCanonicalPathSafe(file));
}
BlazeProjectData projectData =
BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
@@ -41,4 +44,16 @@
file = projectData.workspacePathResolver.resolveToFile(fileString);
return VirtualFileSystemProvider.getInstance().getSystem().findFileByPath(file.getPath());
}
+
+ /**
+ * Swallows {@link IOException}s, falling back to returning the absolute, possibly non-canonical
+ * path.
+ */
+ private static String getCanonicalPathSafe(File file) {
+ try {
+ return file.getCanonicalPath();
+ } catch (IOException e) {
+ return file.getAbsolutePath();
+ }
+ }
}
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..d344018 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;
@@ -61,7 +62,7 @@
if (handlerState == null) {
return false;
}
- handlerState.setCommand(BlazeCommandName.TEST);
+ handlerState.getCommandState().setCommand(BlazeCommandName.TEST);
configuration.setGeneratedName();
return true;
}
@@ -84,7 +85,7 @@
if (handlerState == null) {
return false;
}
- return Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)
+ return Objects.equals(handlerState.getCommandState().getCommand(), BlazeCommandName.TEST)
&& Objects.equals(
configuration.getTarget(), TargetExpression.allFromPackageRecursive(packagePath));
}
@@ -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/producers/BlazeBuildFileRunConfigurationProducer.java b/base/src/com/google/idea/blaze/base/run/producers/BlazeBuildFileRunConfigurationProducer.java
index 60faff7..9a838ed 100644
--- a/base/src/com/google/idea/blaze/base/run/producers/BlazeBuildFileRunConfigurationProducer.java
+++ b/base/src/com/google/idea/blaze/base/run/producers/BlazeBuildFileRunConfigurationProducer.java
@@ -195,8 +195,9 @@
configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
if (handlerState != null) {
// TODO move the old test rule functionality to a BlazeRunConfigurationFactory
- handlerState.setCommand(
- Kind.isTestRule(target.ruleType) ? BlazeCommandName.TEST : BlazeCommandName.BUILD);
+ BlazeCommandName command =
+ Kind.isTestRule(target.ruleType) ? BlazeCommandName.TEST : BlazeCommandName.BUILD;
+ handlerState.getCommandState().setCommand(command);
}
configuration.setGeneratedName();
}
diff --git a/base/src/com/google/idea/blaze/base/run/producers/BlazeFilterExistingRunConfigurationProducer.java b/base/src/com/google/idea/blaze/base/run/producers/BlazeFilterExistingRunConfigurationProducer.java
index feae47b..92089e4 100644
--- a/base/src/com/google/idea/blaze/base/run/producers/BlazeFilterExistingRunConfigurationProducer.java
+++ b/base/src/com/google/idea/blaze/base/run/producers/BlazeFilterExistingRunConfigurationProducer.java
@@ -59,14 +59,20 @@
}
BlazeCommandRunConfigurationCommonState handlerState =
configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
- if (handlerState == null || !BlazeCommandName.TEST.equals(handlerState.getCommand())) {
+ if (handlerState == null
+ || !BlazeCommandName.TEST.equals(handlerState.getCommandState().getCommand())) {
return false;
}
// replace old test filter flag if present
- List<String> flags = new ArrayList<>(handlerState.getBlazeFlags());
+ List<String> flags = new ArrayList<>(handlerState.getBlazeFlagsState().getRawFlags());
flags.removeIf((flag) -> flag.startsWith(BlazeFlags.TEST_FILTER));
flags.add(testFilter);
- handlerState.setBlazeFlags(flags);
+
+ if (SmRunnerUtils.countSelectedTestCases(context) == 1
+ && !flags.contains(BlazeFlags.DISABLE_TEST_SHARDING)) {
+ flags.add(BlazeFlags.DISABLE_TEST_SHARDING);
+ }
+ handlerState.getBlazeFlagsState().setRawFlags(flags);
configuration.setName(configuration.getName() + " (filtered)");
configuration.setNameChangedByUser(true);
return true;
@@ -83,7 +89,7 @@
configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
return handlerState != null
- && Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)
+ && Objects.equals(handlerState.getCommandState().getCommand(), BlazeCommandName.TEST)
&& Objects.equals(testFilter, handlerState.getTestFilterFlag());
}
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/BlazeRerunFailedTestsAction.java b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeRerunFailedTestsAction.java
index 2522bab..578bb9b 100644
--- a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeRerunFailedTestsAction.java
+++ b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeRerunFailedTestsAction.java
@@ -80,13 +80,15 @@
throws ExecutionException {
BlazeCommandRunConfigurationCommonState handlerState =
configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
- if (handlerState == null || !BlazeCommandName.TEST.equals(handlerState.getCommand())) {
+ if (handlerState == null
+ || !BlazeCommandName.TEST.equals(handlerState.getCommandState().getCommand())) {
return null;
}
Project project = getProject();
List<Location<?>> locations =
getFailedTests(project)
.stream()
+ .filter(AbstractTestProxy::isLeaf)
.map((test) -> toLocation(project, test))
.filter(Objects::nonNull)
.collect(Collectors.toList());
@@ -94,8 +96,9 @@
if (testFilter == null) {
return null;
}
- List<String> blazeFlags = setTestFilter(handlerState.getBlazeFlags(), testFilter);
- handlerState.setBlazeFlags(blazeFlags);
+ List<String> blazeFlags =
+ setTestFilter(handlerState.getBlazeFlagsState().getRawFlags(), testFilter);
+ handlerState.getBlazeFlagsState().setRawFlags(blazeFlags);
return configuration.getState(executor, environment);
}
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..3ecdeea 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();
}
@@ -117,16 +116,16 @@
public String testLocationUrl(
@Nullable Kind kind, String parentSuite, String name, @Nullable String className) {
- String base = SmRunnerUtils.GENERIC_TEST_PROTOCOL + URLUtil.SCHEME_SEPARATOR + name;
+ String base = SmRunnerUtils.GENERIC_TEST_PROTOCOL + URLUtil.SCHEME_SEPARATOR;
if (Strings.isNullOrEmpty(className)) {
- return base;
+ return base + name;
}
- return base + SmRunnerUtils.TEST_NAME_PARTS_SPLITTER + className;
+ return base + className + SmRunnerUtils.TEST_NAME_PARTS_SPLITTER + name;
}
/** 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..0cdee3b 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
@@ -22,8 +22,8 @@
import com.google.idea.blaze.base.run.smrunner.BlazeXmlSchema.TestCase;
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.blaze.base.run.testlogs.BlazeTestResultFinderStrategy;
+import com.google.idea.blaze.base.run.testlogs.BlazeTestResults;
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,46 @@
onStartTesting();
getProcessor().onTestsReporterAttached();
- for (CompletedTestTarget testTarget : BlazeTestXmlFinderStrategy.locateTestXmlFiles(project)) {
- try (InputStream input = new FileInputStream(testTarget.testResultXml)) {
- parseXmlInput(getProcessor(), getKind(project, testTarget.label), input);
+ BlazeTestResults testResults = BlazeTestResultFinderStrategy.locateTestResults(project);
+ for (Label target : testResults.failedTargets) {
+ reportFailedTarget(target);
+ }
+ for (Label label : testResults.testXmlFiles.keySet()) {
+ processTestSuites(label, testResults.testXmlFiles.get(label));
+ }
+ }
+
+ private void reportFailedTarget(Label label) {
+ GeneralTestEventsProcessor processor = getProcessor();
+ TestSuiteStarted suiteStarted = new TestSuiteStarted(label.toString());
+ processor.onSuiteStarted(new TestSuiteStartedEvent(suiteStarted, null));
+ String targetName = label.targetName().toString();
+ processor.onTestStarted(new TestStartedEvent(targetName, null));
+ processor.onTestFailure(
+ SmRunnerCompatUtils.getTestFailedEvent(
+ targetName, "Target failed to build. See console output for details", null, 0));
+ processor.onTestFinished(new TestFinishedEvent(targetName, 0L));
+ processor.onSuiteFinished(new TestSuiteFinishedEvent(label.toString()));
+ }
+
+ /** 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 +139,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/smrunner/SmRunnerUtils.java b/base/src/com/google/idea/blaze/base/run/smrunner/SmRunnerUtils.java
index b9e80ba..54f6595 100644
--- a/base/src/com/google/idea/blaze/base/run/smrunner/SmRunnerUtils.java
+++ b/base/src/com/google/idea/blaze/base/run/smrunner/SmRunnerUtils.java
@@ -33,8 +33,10 @@
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.search.GlobalSearchScope;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.swing.tree.TreePath;
@@ -88,6 +90,26 @@
}
public static List<Location<?>> getSelectedSmRunnerTreeElements(ConfigurationContext context) {
+ Project project = context.getProject();
+ List<SMTestProxy> tests = getSelectedTestProxies(context);
+ return tests
+ .stream()
+ .map(test -> (Location<?>) test.getLocation(project, GlobalSearchScope.allScope(project)))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+ /** Counts all selected test cases, and their children, recursively */
+ public static int countSelectedTestCases(ConfigurationContext context) {
+ List<SMTestProxy> tests = getSelectedTestProxies(context);
+ Set<SMTestProxy> allTests = new HashSet<>(tests);
+ for (SMTestProxy test : tests) {
+ allTests.addAll(test.collectChildren());
+ }
+ return allTests.size();
+ }
+
+ private static List<SMTestProxy> getSelectedTestProxies(ConfigurationContext context) {
SMTRunnerTestTreeView treeView =
SMTRunnerTestTreeView.SM_TEST_RUNNER_VIEW.getData(context.getDataContext());
if (treeView == null) {
@@ -98,18 +120,16 @@
return ImmutableList.of();
}
return Arrays.stream(paths)
- .map((path) -> toLocation(context.getProject(), treeView, path))
+ .map((path) -> toTestProxy(treeView, path))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
@Nullable
- private static Location<?> toLocation(
- Project project, SMTRunnerTestTreeView treeView, TreePath path) {
+ private static SMTestProxy toTestProxy(SMTRunnerTestTreeView treeView, TreePath path) {
if (treeView.isPathSelected(path.getParentPath())) {
return null;
}
- SMTestProxy test = treeView.getSelectedTest(path);
- return test != null ? test.getLocation(project, GlobalSearchScope.allScope(project)) : null;
+ return treeView.getSelectedTest(path);
}
}
diff --git a/base/src/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonState.java b/base/src/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonState.java
index ef2ec8e..082f4be 100644
--- a/base/src/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonState.java
+++ b/base/src/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonState.java
@@ -23,7 +23,6 @@
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.openapi.project.Project;
import java.io.File;
-import java.util.List;
import javax.annotation.Nullable;
/**
@@ -49,46 +48,32 @@
addStates(command, blazeFlags, exeFlags, blazeBinary, runOnDistributedExecutor);
}
- @Nullable
- public BlazeCommandName getCommand() {
- return command.getCommand();
- }
-
/** @return The list of blaze flags that the user specified manually. */
- public List<String> getBlazeFlags() {
- return blazeFlags.getFlags();
+ public RunConfigurationFlagsState getBlazeFlagsState() {
+ return blazeFlags;
}
/** @return The list of executable flags the user specified manually. */
- public List<String> getExeFlags() {
- return exeFlags.getFlags();
+ public RunConfigurationFlagsState getExeFlagsState() {
+ return exeFlags;
}
- @Nullable
- public String getBlazeBinary() {
- return blazeBinary.getBlazeBinary();
+ public BlazeBinaryState getBlazeBinaryState() {
+ return blazeBinary;
}
- public void setCommand(@Nullable BlazeCommandName command) {
- this.command.setCommand(command);
+ public BlazeCommandState getCommandState() {
+ return command;
}
- public void setBlazeFlags(List<String> flags) {
- this.blazeFlags.setFlags(flags);
- }
-
- public void setExeFlags(List<String> flags) {
- this.exeFlags.setFlags(flags);
- }
-
- public void setBlazeBinary(@Nullable String blazeBinary) {
- this.blazeBinary.setBlazeBinary(blazeBinary);
+ public BlazeRunOnDistributedExecutorState getRunOnDistributedExecutorState() {
+ return runOnDistributedExecutor;
}
/** Searches through all blaze flags for the first one beginning with '--test_filter' */
@Nullable
public String getTestFilterFlag() {
- for (String flag : getBlazeFlags()) {
+ for (String flag : getBlazeFlagsState().getExpandedFlags()) {
if (flag.startsWith(BlazeFlags.TEST_FILTER)) {
return flag;
}
@@ -96,19 +81,11 @@
return null;
}
- public boolean getRunOnDistributedExecutor() {
- return runOnDistributedExecutor.runOnDistributedExecutor;
- }
-
- public void setRunOnDistributedExecutor(boolean runOnDistributedExecutor) {
- this.runOnDistributedExecutor.runOnDistributedExecutor = runOnDistributedExecutor;
- }
-
public void validate(String buildSystemName) throws RuntimeConfigurationException {
- if (getCommand() == null) {
+ if (getCommandState().getCommand() == null) {
throw new RuntimeConfigurationError("You must specify a command.");
}
- String blazeBinaryString = getBlazeBinary();
+ String blazeBinaryString = getBlazeBinaryState().getBlazeBinary();
if (blazeBinaryString != null && !(new File(blazeBinaryString).exists())) {
throw new RuntimeConfigurationError(buildSystemName + " binary does not exist");
}
@@ -135,7 +112,7 @@
// this editor needs to update based on state provided by other children.
if (runOnExecutorEditor != null) {
- boolean isTest = BlazeCommandName.TEST.equals(state.getCommand());
+ boolean isTest = BlazeCommandName.TEST.equals(state.getCommandState().getCommand());
runOnExecutorEditor.updateVisibility(isTest);
}
}
diff --git a/base/src/com/google/idea/blaze/base/run/state/RunConfigurationFlagsState.java b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationFlagsState.java
index 87d306c..9cb8a3c 100644
--- a/base/src/com/google/idea/blaze/base/run/state/RunConfigurationFlagsState.java
+++ b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationFlagsState.java
@@ -17,6 +17,7 @@
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.ui.UiUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -42,11 +43,17 @@
this.fieldLabel = fieldLabel;
}
- public List<String> getFlags() {
+ /** @return Flags subject to macro expansion. */
+ public List<String> getExpandedFlags() {
+ return BlazeFlags.expandBuildFlags(flags);
+ }
+
+ /** @return Raw flags that haven't been macro expanded */
+ public List<String> getRawFlags() {
return flags;
}
- public void setFlags(List<String> flags) {
+ public void setRawFlags(List<String> flags) {
this.flags = ImmutableList.copyOf(flags);
}
@@ -118,13 +125,13 @@
@Override
public void resetEditorFrom(RunConfigurationState genericState) {
RunConfigurationFlagsState state = (RunConfigurationFlagsState) genericState;
- flagsField.setText(makeFlagString(state.getFlags()));
+ flagsField.setText(makeFlagString(state.getRawFlags()));
}
@Override
public void applyEditorTo(RunConfigurationState genericState) {
RunConfigurationFlagsState state = (RunConfigurationFlagsState) genericState;
- state.setFlags(ParametersListUtil.parse(Strings.nullToEmpty(flagsField.getText())));
+ state.setRawFlags(ParametersListUtil.parse(Strings.nullToEmpty(flagsField.getText())));
}
@Override
diff --git a/base/src/com/google/idea/blaze/base/run/targetfinder/TargetFinder.java b/base/src/com/google/idea/blaze/base/run/targetfinder/TargetFinder.java
index cc88533..23a03a2 100644
--- a/base/src/com/google/idea/blaze/base/run/targetfinder/TargetFinder.java
+++ b/base/src/com/google/idea/blaze/base/run/targetfinder/TargetFinder.java
@@ -35,7 +35,7 @@
@Nullable
public TargetIdeInfo targetForLabel(Project project, final Label label) {
- return findTarget(project, target -> target.key.label.equals(label));
+ return findTarget(project, target -> target.key.label.equals(label) && target.isPlainTarget());
}
public ImmutableList<TargetIdeInfo> targetsOfKinds(Project project, final Kind... kinds) {
diff --git a/base/src/com/google/idea/blaze/base/run/testlogs/BlazeCommandLogParser.java b/base/src/com/google/idea/blaze/base/run/testlogs/BlazeCommandLogParser.java
index 9993c83..6920313 100644
--- a/base/src/com/google/idea/blaze/base/run/testlogs/BlazeCommandLogParser.java
+++ b/base/src/com/google/idea/blaze/base/run/testlogs/BlazeCommandLogParser.java
@@ -36,6 +36,8 @@
private static final Logger logger = Logger.getInstance(BlazeCommandLogParser.class);
private static final Pattern TEST_LOG = Pattern.compile("^(//[^\\s]*) .*? (PASSED|FAILED)");
+ private static final Pattern FAILED_TARGET =
+ Pattern.compile("^Target (//[^\\s]*) failed to build");
/** Finds log location and target label for all tests listed in the master log. */
public static ImmutableSet<Label> parseTestTargets(File commandLog) {
@@ -47,6 +49,25 @@
}
}
+ /** Finds the targets which failed to build */
+ public static ImmutableSet<Label> parseFailedTargets(File commandLog) {
+ try (Stream<String> stream = Files.lines(Paths.get(commandLog.getPath()))) {
+ return parseTestTargets(stream);
+ } catch (IOException e) {
+ logger.warn("Error parsing master log", e);
+ return ImmutableSet.of();
+ }
+ }
+
+ @VisibleForTesting
+ static ImmutableSet<Label> parseFailedTargets(Stream<String> lines) {
+ return ImmutableSet.copyOf(
+ lines
+ .map(BlazeCommandLogParser::parseBuildFailure)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet()));
+ }
+
@VisibleForTesting
static ImmutableSet<Label> parseTestTargets(Stream<String> lines) {
return ImmutableSet.copyOf(
@@ -65,4 +86,14 @@
}
return Label.createIfValid(match.group(1));
}
+
+ @Nullable
+ @VisibleForTesting
+ static Label parseBuildFailure(String line) {
+ Matcher match = FAILED_TARGET.matcher(line);
+ if (!match.find()) {
+ return null;
+ }
+ return Label.createIfValid(match.group(1));
+ }
}
diff --git a/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestResultFinderStrategy.java b/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestResultFinderStrategy.java
new file mode 100644
index 0000000..cff8bd4
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestResultFinderStrategy.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.base.run.testlogs;
+
+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 javax.annotation.Nullable;
+
+/** A strategy for locating results from 'blaze test' invocation (e.g. output XML files). */
+public interface BlazeTestResultFinderStrategy {
+
+ ExtensionPointName<BlazeTestResultFinderStrategy> EP_NAME =
+ ExtensionPointName.create("com.google.idea.blaze.BlazeTestXmlFinderStrategy");
+
+ /**
+ * Attempt to find all output test XML files produced by the most recent blaze invocation, grouped
+ * by target label.
+ */
+ @Nullable
+ static BlazeTestResults locateTestResults(Project project) {
+ BuildSystem buildSystem = Blaze.getBuildSystem(project);
+ for (BlazeTestResultFinderStrategy strategy : EP_NAME.getExtensions()) {
+ if (strategy.handlesBuildSystem(buildSystem)) {
+ return strategy.findTestResults(project);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Attempt to find test results corresponding to the most recent blaze invocation. Called after
+ * the 'blaze test' process completes.
+ */
+ @Nullable
+ BlazeTestResults findTestResults(Project project);
+
+ /** Results are taken from the first strategy handling a given build system */
+ boolean handlesBuildSystem(BuildSystem buildSystem);
+}
diff --git a/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestResults.java b/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestResults.java
new file mode 100644
index 0000000..7d50bf2
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestResults.java
@@ -0,0 +1,36 @@
+/*
+ * 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.testlogs;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.idea.blaze.base.model.primitives.Label;
+import java.io.File;
+
+/** Results from a 'blaze test' invocation. */
+public class BlazeTestResults {
+
+ /** Output test XML files, grouped by target label. */
+ public final ImmutableMultimap<Label, File> testXmlFiles;
+ /** Targets which failed to build */
+ public final ImmutableSet<Label> failedTargets;
+
+ public BlazeTestResults(
+ ImmutableMultimap<Label, File> testXmlFiles, ImmutableSet<Label> failedTargets) {
+ this.testXmlFiles = testXmlFiles;
+ this.failedTargets = failedTargets;
+ }
+}
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
deleted file mode 100644
index 174d512..0000000
--- a/base/src/com/google/idea/blaze/base/run/testlogs/BlazeTestXmlFinderStrategy.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.testlogs;
-
-import com.google.common.collect.ImmutableList;
-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;
-
-/** A strategy for locating output test XML files. */
-public interface BlazeTestXmlFinderStrategy {
-
- ExtensionPointName<BlazeTestXmlFinderStrategy> EP_NAME =
- 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.
- */
- static ImmutableList<CompletedTestTarget> locateTestXmlFiles(Project project) {
- BuildSystem buildSystem = Blaze.getBuildSystem(project);
- ImmutableList.Builder<CompletedTestTarget> output = ImmutableList.builder();
- for (BlazeTestXmlFinderStrategy strategy : EP_NAME.getExtensions()) {
- if (strategy.handlesBuildSystem(buildSystem)) {
- output.addAll(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.
- */
- ImmutableList<CompletedTestTarget> 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/TargetPathTestResultFinderStrategy.java
similarity index 75%
rename from base/src/com/google/idea/blaze/base/run/testlogs/TargetPathTestXmlFinderStrategy.java
rename to base/src/com/google/idea/blaze/base/run/testlogs/TargetPathTestResultFinderStrategy.java
index ce5ec40..c18cc65 100644
--- a/base/src/com/google/idea/blaze/base/run/testlogs/TargetPathTestXmlFinderStrategy.java
+++ b/base/src/com/google/idea/blaze/base/run/testlogs/TargetPathTestResultFinderStrategy.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,15 +24,13 @@
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;
/**
* Attempts to parse the list of test targets from the command log, then searches the corresponding
* path in the bazel-testlogs output tree.
*/
-public class TargetPathTestXmlFinderStrategy implements BlazeTestXmlFinderStrategy {
+public class TargetPathTestResultFinderStrategy implements BlazeTestResultFinderStrategy {
@Override
public boolean handlesBuildSystem(BuildSystem buildSystem) {
@@ -40,28 +38,30 @@
}
@Override
- public ImmutableList<CompletedTestTarget> findTestXmlFiles(Project project) {
+ public BlazeTestResults findTestResults(Project project) {
File testLogsDir = getTestLogsTree(project);
if (testLogsDir == null) {
- return ImmutableList.of();
+ return null;
}
File commandLog = getCommandLog(project);
if (commandLog == null) {
- return ImmutableList.of();
+ return null;
}
- 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 new BlazeTestResults(
+ output.build(), BlazeCommandLogParser.parseFailedTargets(commandLog));
}
@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..e288d8a 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,9 @@
package com.google.idea.blaze.base.scope;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProcessCanceledException;
+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 {
@@ -34,6 +35,9 @@
BlazeContext context = new BlazeContext(parentContext);
try {
return scopedFunction.execute(context);
+ } catch (ProcessCanceledException e) {
+ context.setCancelled();
+ throw e;
} catch (RuntimeException e) {
context.setHasError();
logger.error(e);
@@ -54,6 +58,9 @@
BlazeContext context = new BlazeContext(parentContext);
try {
scopedOperation.execute(context);
+ } catch (ProcessCanceledException e) {
+ context.setCancelled();
+ throw e;
} catch (RuntimeException e) {
context.setHasError();
logger.error(e);
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 {