Project import generated by Copybara.
diff --git a/BUILD b/BUILD
index 9d98461..81608fe 100644
--- a/BUILD
+++ b/BUILD
@@ -31,6 +31,7 @@
name = "clwb_tests",
tests = [
"//base:unit_tests",
+ "//cpp:unit_tests",
],
)
diff --git a/WORKSPACE b/WORKSPACE
index f443141..485d46f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -5,7 +5,7 @@
new_http_archive(
name = "intellij_latest",
build_file = "intellij_platform_sdk/BUILD.idea",
- url = "https://download.jetbrains.com/idea/ideaIC-2016.2.1.tar.gz",
+ url = "https://download.jetbrains.com/idea/ideaIC-2016.2.4.tar.gz",
)
# The plugin api for CLion 2016.1.3. This is required to build CLwB,
@@ -13,7 +13,7 @@
new_http_archive(
name = "clion_latest",
build_file = "intellij_platform_sdk/BUILD.clion",
- url = "https://download.jetbrains.com/cpp/CLion-2016.2.1.tar.gz",
+ url = "https://download.jetbrains.com/cpp/CLion-2016.2.2.tar.gz",
)
# The plugin api for Android Studio 2.2 stable. This is required to build ASwB,
diff --git a/aswb/BUILD b/aswb/BUILD
index 2312a96..6e4a3a2 100644
--- a/aswb/BUILD
+++ b/aswb/BUILD
@@ -61,7 +61,7 @@
)
load(
- "//intellij_test:test_defs.bzl",
+ "//testing:test_defs.bzl",
"intellij_unit_test_suite",
)
diff --git a/aswb/.bazelproject b/aswb/aswb.bazelproject
similarity index 70%
rename from aswb/.bazelproject
rename to aswb/aswb.bazelproject
index 2fdb3b8..34cbb52 100644
--- a/aswb/.bazelproject
+++ b/aswb/aswb.bazelproject
@@ -1,13 +1,12 @@
directories:
.
-ijwb
- -blaze-plugin-dev
+ -plugin_dev
-clwb
- -blaze-cpp/src/com/google/idea/blaze/cpp/versioned/v162
+ -cpp/src/com/google/idea/blaze/cpp/versioned/v162
targets:
//aswb:aswb_bazel
- //aswb:aswb_blaze
//:aswb_tests
workspace_type: intellij_plugin
diff --git a/aswb/src/META-INF/aswb.xml b/aswb/src/META-INF/aswb.xml
index f7b42c3..d8d9334 100644
--- a/aswb/src/META-INF/aswb.xml
+++ b/aswb/src/META-INF/aswb.xml
@@ -51,7 +51,7 @@
<SyncListener implementation="com.google.idea.blaze.android.sync.BlazeAndroidSyncListener"/>
<SyncListener implementation="com.google.idea.blaze.android.cppimpl.BlazeNdkSupportEnabler"/>
<SyncListener implementation="com.google.idea.blaze.android.manifest.ManifestParser$ClearManifestParser"/>
- <RuleConfigurationFactory implementation="com.google.idea.blaze.android.run.BlazeAndroidRuleConfigurationFactory"/>
+ <RunConfigurationFactory implementation="com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationFactory"/>
<java.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"/>
diff --git a/aswb/src/META-INF/aswb_bazel.xml b/aswb/src/META-INF/aswb_bazel.xml
index 4b89d60..4d50f16 100644
--- a/aswb/src/META-INF/aswb_bazel.xml
+++ b/aswb/src/META-INF/aswb_bazel.xml
@@ -14,5 +14,18 @@
~ limitations under the License.
-->
<idea-plugin>
- <description>Provides the ability to import Bazel projects in Android Studio.</description>
+ <description>
+ <![CDATA[
+ <a href="http://bazel.io">Bazel</a> support for Android Studio.
+
+ Features:
+ <ul>
+ <li>Import BUILD files into the IDE.</li>
+ <li>BUILD file custom language support.</li>
+ <li>Support for Bazel run configurations for certain rule classes.</li>
+ </ul>
+
+ Usage instructions at <a href="http://ij.bazel.io">ij.bazel.io</a>
+ ]]>
+ </description>
</idea-plugin>
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 1918b2c..3087e9a 100644
--- a/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java
+++ b/aswb/src/com/google/idea/blaze/android/cppimpl/BlazeNdkSupportEnabler.java
@@ -21,6 +21,7 @@
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.SyncListener;
import com.google.idea.blaze.cpp.BlazeCWorkspace;
@@ -34,6 +35,7 @@
@Override
public void onSyncComplete(
Project project,
+ BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
diff --git a/aswb/src/com/google/idea/blaze/android/manifest/ManifestParser.java b/aswb/src/com/google/idea/blaze/android/manifest/ManifestParser.java
index 00cbe6b..a8fe734 100644
--- a/aswb/src/com/google/idea/blaze/android/manifest/ManifestParser.java
+++ b/aswb/src/com/google/idea/blaze/android/manifest/ManifestParser.java
@@ -18,6 +18,7 @@
import com.google.common.collect.Maps;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.SyncListener;
import com.intellij.openapi.application.ApplicationManager;
@@ -98,6 +99,7 @@
@Override
public void onSyncComplete(
Project project,
+ BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
diff --git a/aswb/src/com/google/idea/blaze/android/resources/AndroidPackageRClass.java b/aswb/src/com/google/idea/blaze/android/resources/AndroidPackageRClass.java
index b1802aa..66f42df 100644
--- a/aswb/src/com/google/idea/blaze/android/resources/AndroidPackageRClass.java
+++ b/aswb/src/com/google/idea/blaze/android/resources/AndroidPackageRClass.java
@@ -16,7 +16,6 @@
package com.google.idea.blaze.android.resources;
import com.android.resources.ResourceType;
-import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
@@ -27,7 +26,7 @@
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.CachedValue;
-import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValueProvider.Result;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import java.util.ArrayList;
@@ -44,8 +43,6 @@
/** Represents a dynamic "class R" for resources in an Android module. */
public class AndroidPackageRClass extends AndroidLightClassBase {
private static final Logger LOG = Logger.getInstance(AndroidPackageRClass.class);
- private static final BoolExperiment USE_OUT_OF_CODE_MOD_COUNT =
- new BoolExperiment("use.out.of.code.modcount.for.r.class.cache", true);
@NotNull private final PsiFile myFile;
@NotNull private final String myFullyQualifiedName;
@@ -108,16 +105,10 @@
myClassCache =
CachedValuesManager.getManager(getProject())
.createCachedValue(
- new CachedValueProvider<PsiClass[]>() {
- @Override
- public Result<PsiClass[]> compute() {
- return Result.create(
+ () ->
+ Result.create(
doGetInnerClasses(),
- USE_OUT_OF_CODE_MOD_COUNT.getValue()
- ? PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
- : PsiModificationTracker.MODIFICATION_COUNT);
- }
- });
+ PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT));
}
return myClassCache.getValue();
}
@@ -136,7 +127,7 @@
final Set<ResourceType> types =
ResourceReferenceConverter.getResourceTypesInCurrentModule(facet);
- final List<PsiClass> result = new ArrayList<PsiClass>();
+ final List<PsiClass> result = new ArrayList<>();
for (ResourceType type : types) {
result.add(new ResourceTypeClass(facet, type.getName(), this));
diff --git a/aswb/src/com/google/idea/blaze/android/resources/actions/BlazeCreateResourceUtils.java b/aswb/src/com/google/idea/blaze/android/resources/actions/BlazeCreateResourceUtils.java
index 2b98ee9..20f88d2 100644
--- a/aswb/src/com/google/idea/blaze/android/resources/actions/BlazeCreateResourceUtils.java
+++ b/aswb/src/com/google/idea/blaze/android/resources/actions/BlazeCreateResourceUtils.java
@@ -21,10 +21,11 @@
import com.google.common.collect.Sets;
import com.google.idea.blaze.android.sync.model.AndroidResourceModule;
import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.rulemaps.SourceToRuleMap;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.ide.util.DirectoryUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
@@ -37,6 +38,7 @@
import com.intellij.ui.ComboboxWithBrowseButton;
import com.intellij.ui.components.JBLabel;
import java.io.File;
+import java.util.Collection;
import java.util.Set;
import javax.swing.JComboBox;
import org.jetbrains.annotations.Nullable;
@@ -59,16 +61,19 @@
if (blazeProjectData != null) {
BlazeAndroidSyncData syncData = blazeProjectData.syncState.get(BlazeAndroidSyncData.class);
if (syncData != null) {
- ImmutableCollection<Label> labelsRelatedToContext = null;
+ ImmutableCollection<RuleKey> rulesRelatedToContext = null;
File fileFromContext = null;
if (contextFile != null) {
fileFromContext = VfsUtilCore.virtualToIoFile(contextFile);
- labelsRelatedToContext =
- SourceToRuleMap.getInstance(project).getTargetsForSourceFile(fileFromContext);
- if (labelsRelatedToContext.isEmpty()) {
- labelsRelatedToContext = null;
+ rulesRelatedToContext =
+ SourceToRuleMap.getInstance(project).getRulesForSourceFile(fileFromContext);
+ if (rulesRelatedToContext.isEmpty()) {
+ rulesRelatedToContext = null;
}
}
+
+ ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
+
// Sort:
// - contextFile/res if contextFile is a directory,
// to optimize the right click on directory case, or the "closest" string
@@ -81,20 +86,24 @@
Set<File> allResDirs = Sets.newTreeSet();
for (AndroidResourceModule androidResourceModule :
syncData.importResult.androidResourceModules) {
+
+ Collection<File> resources =
+ artifactLocationDecoder.decodeAll(androidResourceModule.resources);
+
+ Collection<File> transitiveResources =
+ artifactLocationDecoder.decodeAll(androidResourceModule.transitiveResources);
+
// labelsRelatedToContext should include deps,
// but as a first pass we only check the rules themselves
// for resources. If we come up empty, then have anyResDir as a backup.
- allResDirs.addAll(androidResourceModule.transitiveResources);
- if (labelsRelatedToContext != null
- && !labelsRelatedToContext.contains(androidResourceModule.label)) {
+ allResDirs.addAll(transitiveResources);
+
+ if (rulesRelatedToContext != null
+ && !rulesRelatedToContext.contains(androidResourceModule.ruleKey)) {
continue;
}
- for (File resDir : androidResourceModule.resources) {
- resourceDirs.add(resDir);
- }
- for (File resDir : androidResourceModule.transitiveResources) {
- transitiveDirs.add(resDir);
- }
+ resourceDirs.addAll(resources);
+ transitiveDirs.addAll(transitiveResources);
}
// No need to show some directories twice.
transitiveDirs.removeAll(resourceDirs);
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 2acea9b..ed7a367 100644
--- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java
+++ b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonState.java
@@ -17,34 +17,68 @@
import static com.google.idea.blaze.android.cppapi.NdkSupport.NDK_SUPPORT;
+import com.android.tools.idea.run.ValidationError;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.idea.blaze.android.cppapi.NdkSupport;
+import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationDebuggerManager;
+import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationDeployTargetManager;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.run.state.RunConfigurationFlagsState;
+import com.google.idea.blaze.base.run.state.RunConfigurationState;
+import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
+import com.google.idea.blaze.base.ui.UiUtil;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
+import java.awt.Component;
import java.util.List;
+import javax.annotation.Nullable;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
import org.jdom.Element;
+import org.jetbrains.android.facet.AndroidFacet;
-/**
- * A shared state class for run configurations targeting Blaze Android rules. We implement the
- * deprecated JDomExternalizable to fit with the other run configs.
- */
-public class BlazeAndroidRunConfigurationCommonState implements BlazeAndroidRunConfigurationState {
+/** A shared state class for run configurations targeting Blaze Android rules. */
+public class BlazeAndroidRunConfigurationCommonState implements RunConfigurationState {
private static final String USER_FLAG_TAG = "blaze-user-flag";
private static final String NATIVE_DEBUG_ATTR = "blaze-native-debug";
- private List<String> userFlags;
+ // We need to split "-c dbg" into two flags because we pass flags
+ // as a list of strings to the command line executor and we need blaze
+ // to see -c and dbg as two separate entities, not one.
+ private static final ImmutableList<String> NATIVE_DEBUG_FLAGS =
+ ImmutableList.of("--fission=no", "-c", "dbg");
+
+ private final BlazeAndroidRunConfigurationDeployTargetManager deployTargetManager;
+ private final BlazeAndroidRunConfigurationDebuggerManager debuggerManager;
+
+ private final RunConfigurationFlagsState userFlags;
private boolean nativeDebuggingEnabled = false;
- /** Creates a configuration state initialized with the given flags. */
- public BlazeAndroidRunConfigurationCommonState(List<String> userFlags) {
- this.userFlags = userFlags;
+ public BlazeAndroidRunConfigurationCommonState(String buildSystemName, boolean isAndroidTest) {
+ this.deployTargetManager = new BlazeAndroidRunConfigurationDeployTargetManager(isAndroidTest);
+ this.debuggerManager = new BlazeAndroidRunConfigurationDebuggerManager(this);
+ this.userFlags =
+ new RunConfigurationFlagsState(
+ USER_FLAG_TAG, String.format("Custom %s build flags:", buildSystemName));
+ }
+
+ public BlazeAndroidRunConfigurationDeployTargetManager getDeployTargetManager() {
+ return deployTargetManager;
+ }
+
+ public BlazeAndroidRunConfigurationDebuggerManager getDebuggerManager() {
+ return debuggerManager;
}
public List<String> getUserFlags() {
- return userFlags;
+ return userFlags.getFlags();
}
public void setUserFlags(List<String> userFlags) {
- this.userFlags = userFlags;
+ this.userFlags.setFlags(userFlags);
}
public boolean isNativeDebuggingEnabled() {
@@ -55,26 +89,91 @@
this.nativeDebuggingEnabled = nativeDebuggingEnabled;
}
+ public ImmutableList<String> getBuildFlags(Project project, ProjectViewSet projectViewSet) {
+ return ImmutableList.<String>builder()
+ .addAll(BlazeFlags.buildFlags(project, projectViewSet))
+ .addAll(getUserFlags())
+ .addAll(getNativeDebuggerFlags())
+ .build();
+ }
+
+ private ImmutableList<String> getNativeDebuggerFlags() {
+ return isNativeDebuggingEnabled() ? NATIVE_DEBUG_FLAGS : ImmutableList.of();
+ }
+
+ /**
+ * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a
+ * warning.
+ */
+ public List<ValidationError> validate(@Nullable AndroidFacet facet) {
+ List<ValidationError> errors = Lists.newArrayList();
+ // If facet is null, we can't validate the managers, but that's fine because
+ // BlazeAndroidRunConfigurationValidationUtil.validateFacet will give a fatal error.
+ if (facet != null) {
+ errors.addAll(deployTargetManager.validate(facet));
+ errors.addAll(debuggerManager.validate(facet));
+ }
+ return errors;
+ }
+
@Override
public void readExternal(Element element) throws InvalidDataException {
- ImmutableList.Builder<String> flagsBuilder = ImmutableList.builder();
- for (Element e : element.getChildren(USER_FLAG_TAG)) {
- String flag = e.getTextTrim();
- if (flag != null && !flag.isEmpty()) {
- flagsBuilder.add(flag);
- }
- }
- userFlags = flagsBuilder.build();
+ userFlags.readExternal(element);
setNativeDebuggingEnabled(Boolean.parseBoolean(element.getAttributeValue(NATIVE_DEBUG_ATTR)));
+
+ deployTargetManager.readExternal(element);
+ debuggerManager.readExternal(element);
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
- for (String flag : userFlags) {
- Element child = new Element(USER_FLAG_TAG);
- child.setText(flag);
- element.addContent(child);
- }
+ userFlags.writeExternal(element);
element.setAttribute(NATIVE_DEBUG_ATTR, Boolean.toString(nativeDebuggingEnabled));
+
+ deployTargetManager.writeExternal(element);
+ debuggerManager.writeExternal(element);
+ }
+
+ @Override
+ public RunConfigurationStateEditor getEditor(Project project) {
+ return new BlazeAndroidRunConfigurationCommonStateEditor(this, project);
+ }
+
+ private static class BlazeAndroidRunConfigurationCommonStateEditor
+ implements RunConfigurationStateEditor {
+
+ private final RunConfigurationStateEditor userFlagsEditor;
+ private final JCheckBox enableNativeDebuggingCheckBox;
+
+ BlazeAndroidRunConfigurationCommonStateEditor(
+ BlazeAndroidRunConfigurationCommonState state, Project project) {
+ userFlagsEditor = state.userFlags.getEditor(project);
+ enableNativeDebuggingCheckBox = new JCheckBox("Enable native debugging", false);
+ }
+
+ @Override
+ public void resetEditorFrom(RunConfigurationState genericState) {
+ BlazeAndroidRunConfigurationCommonState state =
+ (BlazeAndroidRunConfigurationCommonState) genericState;
+ userFlagsEditor.resetEditorFrom(state.userFlags);
+ enableNativeDebuggingCheckBox.setSelected(state.isNativeDebuggingEnabled());
+ }
+
+ @Override
+ public void applyEditorTo(RunConfigurationState genericState) {
+ BlazeAndroidRunConfigurationCommonState state =
+ (BlazeAndroidRunConfigurationCommonState) genericState;
+ userFlagsEditor.applyEditorTo(state.userFlags);
+ state.setNativeDebuggingEnabled(enableNativeDebuggingCheckBox.isSelected());
+ }
+
+ @Override
+ public JComponent createComponent() {
+ List<Component> result = Lists.newArrayList(userFlagsEditor.createComponent());
+ if (NdkSupport.NDK_SUPPORT.getValue()) {
+ result.add(enableNativeDebuggingCheckBox);
+ }
+ return UiUtil.createBox(result);
+ }
}
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateEditor.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateEditor.java
deleted file mode 100644
index 3a0c511..0000000
--- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateEditor.java
+++ /dev/null
@@ -1,69 +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 com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.idea.blaze.android.cppapi.NdkSupport;
-import com.google.idea.blaze.base.settings.Blaze;
-import com.intellij.openapi.project.Project;
-import com.intellij.util.execution.ParametersListUtil;
-import java.util.List;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JTextArea;
-
-/**
- * A simplified, Blaze-specific variant of {@link
- * org.jetbrains.android.run.AndroidRunConfigurationEditor}.
- */
-public class BlazeAndroidRunConfigurationCommonStateEditor {
- private final Project project;
- private final JTextArea userFlagsField;
- private final JCheckBox enableNativeDebuggingCheckBox;
-
- public BlazeAndroidRunConfigurationCommonStateEditor(Project project) {
- this.project = project;
-
- userFlagsField = new JTextArea(3 /* rows */, 50 /* columns */);
- userFlagsField.setToolTipText("e.g. --config=android_arm");
- enableNativeDebuggingCheckBox = new JCheckBox("Enable native debugging", false);
- }
-
- public void resetEditorFrom(BlazeAndroidRunConfigurationCommonState runConfigurationState) {
- userFlagsField.setText(ParametersListUtil.join(runConfigurationState.getUserFlags()));
- enableNativeDebuggingCheckBox.setSelected(runConfigurationState.isNativeDebuggingEnabled());
- }
-
- public void applyEditorTo(BlazeAndroidRunConfigurationCommonState runConfigurationState) {
- List<String> userFlags =
- ParametersListUtil.parse(Strings.nullToEmpty(userFlagsField.getText()));
- runConfigurationState.setUserFlags(userFlags);
- runConfigurationState.setNativeDebuggingEnabled(enableNativeDebuggingCheckBox.isSelected());
- }
-
- public List<JComponent> getComponents() {
- List<JComponent> result =
- Lists.newArrayList(
- new JLabel(String.format("Custom %s build flags:", Blaze.buildSystemName(project))),
- userFlagsField);
- if (NdkSupport.NDK_SUPPORT.getValue()) {
- result.add(enableNativeDebuggingCheckBox);
- }
- return result;
- }
-}
diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRuleConfigurationFactory.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationFactory.java
similarity index 68%
rename from aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRuleConfigurationFactory.java
rename to aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationFactory.java
index 008982a..d398ece 100644
--- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRuleConfigurationFactory.java
+++ b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationFactory.java
@@ -16,20 +16,23 @@
package com.google.idea.blaze.android.run;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+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.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.BlazeRuleConfigurationFactory;
-import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
+import com.google.idea.blaze.base.run.BlazeRunConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.openapi.project.Project;
/** Creates run configurations for android_binary and android_test. */
-public class BlazeAndroidRuleConfigurationFactory extends BlazeRuleConfigurationFactory {
+public class BlazeAndroidRunConfigurationFactory extends BlazeRunConfigurationFactory {
@Override
- public boolean handlesRule(
- WorkspaceLanguageSettings workspaceLanguageSettings, RuleIdeInfo rule) {
- return rule.kindIsOneOf(Kind.ANDROID_BINARY, Kind.ANDROID_TEST);
+ public boolean handlesTarget(Project project, BlazeProjectData blazeProjectData, Label target) {
+ RuleIdeInfo rule = blazeProjectData.ruleMap.get(RuleKey.forPlainTarget(target));
+ return rule != null && rule.kindIsOneOf(Kind.ANDROID_BINARY, Kind.ANDROID_TEST);
}
@Override
@@ -38,9 +41,9 @@
}
@Override
- public void setupConfiguration(RunConfiguration configuration, RuleIdeInfo rule) {
+ public void setupConfiguration(RunConfiguration configuration, Label target) {
final BlazeCommandRunConfiguration blazeConfig = (BlazeCommandRunConfiguration) configuration;
- blazeConfig.setTarget(rule.label);
+ blazeConfig.setTarget(target);
blazeConfig.setGeneratedName();
}
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationHandler.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationHandler.java
index ed5a394..14f00b9 100644
--- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationHandler.java
+++ b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationHandler.java
@@ -15,15 +15,10 @@
*/
package com.google.idea.blaze.android.run;
-import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
import com.intellij.execution.configurations.RunProfile;
-import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.project.Project;
-import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.Nullable;
/** Common interface for Blaze Android run configuration handlers. */
@@ -39,16 +34,16 @@
if (!(profile instanceof BlazeCommandRunConfiguration)) {
return null;
}
- BlazeCommandRunConfiguration blazeConfiguration = (BlazeCommandRunConfiguration) profile;
- return blazeConfiguration.getHandlerIfType(BlazeAndroidRunConfigurationHandler.class);
+ BlazeCommandRunConfigurationHandler handler =
+ ((BlazeCommandRunConfiguration) profile).getHandler();
+ if (!(handler instanceof BlazeAndroidRunConfigurationHandler)) {
+ return null;
+ }
+ return (BlazeAndroidRunConfigurationHandler) handler;
}
- /** @return A {@link BlazeAndroidRunContext} for this handler with the given settings. */
- BlazeAndroidRunContext createRunContext(
- Project project,
- AndroidFacet facet,
- ExecutionEnvironment env,
- ImmutableList<String> buildFlags);
+ /** @return This handler's common state. */
+ BlazeAndroidRunConfigurationCommonState getCommonState();
/**
* @return The {@link Label} this handler's configuration targets, or null if it does not target a
@@ -56,10 +51,4 @@
*/
@Nullable
Label getLabel();
-
- /** @return This handler's common state. */
- BlazeAndroidRunConfigurationCommonState getCommonState();
-
- /** @return This handler's type-specific state. */
- BlazeAndroidRunConfigurationState getConfigState();
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationHandlerEditor.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationHandlerEditor.java
deleted file mode 100644
index e23f0a8..0000000
--- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationHandlerEditor.java
+++ /dev/null
@@ -1,65 +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 com.google.common.collect.Lists;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerEditor;
-import com.google.idea.blaze.base.ui.UiUtil;
-import com.intellij.openapi.project.Project;
-import java.awt.Component;
-import java.util.List;
-import javax.swing.JComponent;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * A simplified, Blaze-specific variant of {@link
- * org.jetbrains.android.run.AndroidRunConfigurationEditor}.
- */
-public class BlazeAndroidRunConfigurationHandlerEditor
- implements BlazeCommandRunConfigurationHandlerEditor {
- private final BlazeAndroidRunConfigurationCommonStateEditor commonStateEditor;
- private final BlazeAndroidRunConfigurationStateEditor kindSpecificEditor;
-
- public BlazeAndroidRunConfigurationHandlerEditor(
- Project project, BlazeAndroidRunConfigurationStateEditor kindSpecificEditor) {
- this.commonStateEditor = new BlazeAndroidRunConfigurationCommonStateEditor(project);
- this.kindSpecificEditor = kindSpecificEditor;
- }
-
- @Override
- public void resetEditorFrom(BlazeCommandRunConfigurationHandler h) {
- BlazeAndroidRunConfigurationHandler handler = (BlazeAndroidRunConfigurationHandler) h;
- commonStateEditor.resetEditorFrom(handler.getCommonState());
- kindSpecificEditor.resetEditorFrom(handler.getConfigState());
- }
-
- @Override
- public void applyEditorTo(BlazeCommandRunConfigurationHandler h) {
- BlazeAndroidRunConfigurationHandler handler = (BlazeAndroidRunConfigurationHandler) h;
- commonStateEditor.applyEditorTo(handler.getCommonState());
- kindSpecificEditor.applyEditorTo(handler.getConfigState());
- }
-
- @Override
- @NotNull
- public JComponent createEditor() {
- List<Component> components = Lists.newArrayList();
- components.addAll(commonStateEditor.getComponents());
- components.add(kindSpecificEditor.getComponent());
- return UiUtil.createBox(components);
- }
-}
diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationState.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationState.java
deleted file mode 100644
index 1d13b56..0000000
--- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationState.java
+++ /dev/null
@@ -1,21 +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 com.intellij.openapi.util.JDOMExternalizable;
-
-/** Indicates a class stores state for a Blaze Android run configuration. */
-public interface BlazeAndroidRunConfigurationState extends JDOMExternalizable {}
diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationStateEditor.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationStateEditor.java
deleted file mode 100644
index 7cbd815..0000000
--- a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationStateEditor.java
+++ /dev/null
@@ -1,28 +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 java.awt.Component;
-
-/** An editor for Blaze Android run configuration state. */
-public interface BlazeAndroidRunConfigurationStateEditor {
-
- void resetEditorFrom(BlazeAndroidRunConfigurationState state);
-
- void applyEditorTo(BlazeAndroidRunConfigurationState state);
-
- Component getComponent();
-}
diff --git a/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationValidationUtil.java b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationValidationUtil.java
new file mode 100644
index 0000000..2c0c26e
--- /dev/null
+++ b/aswb/src/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationValidationUtil.java
@@ -0,0 +1,137 @@
+/*
+ * 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 com.android.tools.idea.gradle.util.Projects;
+import com.android.tools.idea.run.ValidationError;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Ordering;
+import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.model.primitives.Kind;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.RuntimeConfigurationError;
+import com.intellij.execution.configurations.RuntimeConfigurationException;
+import com.intellij.execution.configurations.RuntimeConfigurationWarning;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.jetbrains.android.facet.AndroidFacet;
+import org.jetbrains.android.util.AndroidBundle;
+
+/**
+ * Utility class for validating {@link BlazeAndroidRunConfigurationHandler}s. We collect
+ * configuration errors rather than throwing to avoid missing fatal errors by exiting early for a
+ * warning.
+ */
+public final class BlazeAndroidRunConfigurationValidationUtil {
+
+ private static final String SYNC_FAILED_ERR_MSG =
+ "Project state is invalid. Please sync and try your action again.";
+
+ /**
+ * Finds the top error, as determined by {@link ValidationError#compareTo(Object)}. If it is
+ * fatal, it is thrown as a {@link RuntimeConfigurationError}; otherwise it is thrown as a {@link
+ * RuntimeConfigurationWarning}. If no errors exist, nothing is thrown.
+ */
+ public static void throwTopConfigurationError(List<ValidationError> errors)
+ throws RuntimeConfigurationException {
+ if (errors.isEmpty()) {
+ return;
+ }
+ // TODO: Do something with the extra error information? Error count?
+ ValidationError topError = Ordering.natural().max(errors);
+ if (topError.isFatal()) {
+ throw new RuntimeConfigurationError(topError.getMessage(), topError.getQuickfix());
+ }
+ throw new RuntimeConfigurationWarning(topError.getMessage(), topError.getQuickfix());
+ }
+
+ public static List<ValidationError> validateModule(@Nullable Module module) {
+ List<ValidationError> errors = Lists.newArrayList();
+ if (module == null) {
+ errors.add(
+ ValidationError.fatal(
+ "No run configuration module found. Have you successfully synced your project?"));
+ return errors;
+ }
+ final Project project = module.getProject();
+ if (Projects.requiredAndroidModelMissing(project)) {
+ errors.add(ValidationError.fatal(SYNC_FAILED_ERR_MSG));
+ }
+ return errors;
+ }
+
+ public static List<ValidationError> validateFacet(@Nullable AndroidFacet facet, Module module) {
+ List<ValidationError> errors = Lists.newArrayList();
+ if (facet == null) {
+ errors.add(ValidationError.fatal(AndroidBundle.message("no.facet.error", module.getName())));
+ return errors;
+ }
+ if (facet.getConfiguration().getAndroidPlatform() == null) {
+ errors.add(ValidationError.fatal(AndroidBundle.message("select.platform.error")));
+ }
+ return errors;
+ }
+
+ public static List<ValidationError> validateLabel(
+ @Nullable Label label, Project project, Kind kind) {
+ List<ValidationError> errors = Lists.newArrayList();
+ if (label == null) {
+ errors.add(ValidationError.fatal("No target selected."));
+ return errors;
+ }
+ RuleIdeInfo rule = RuleFinder.getInstance().ruleForTarget(project, label);
+ if (rule == null) {
+ errors.add(
+ ValidationError.fatal(
+ String.format("No existing %s rule selected.", Blaze.buildSystemName(project))));
+ } else if (!rule.kindIsOneOf(kind)) {
+ errors.add(
+ ValidationError.fatal(
+ String.format(
+ "Selected %s rule is not %s", Blaze.buildSystemName(project), kind.toString())));
+ }
+ return errors;
+ }
+
+ public static void validateExecution(
+ @Nullable Module module,
+ @Nullable AndroidFacet facet,
+ @Nullable ProjectViewSet projectViewSet)
+ throws ExecutionException {
+ List<ValidationError> errors = Lists.newArrayList();
+ errors.addAll(validateModule(module));
+ if (module != null) {
+ errors.addAll(validateFacet(facet, module));
+ }
+ if (projectViewSet == null) {
+ errors.add(ValidationError.fatal("Could not load project view. Please resync project"));
+ }
+
+ if (errors.isEmpty()) {
+ return;
+ }
+ ValidationError topError = Ordering.natural().max(errors);
+ if (topError.isFatal()) {
+ throw new ExecutionException(topError.getMessage());
+ }
+ }
+}
diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java
index 5c41e6a..37619aa 100644
--- a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java
+++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryProgramRunner.java
@@ -51,7 +51,7 @@
if (!(handler instanceof BlazeAndroidBinaryRunConfigurationHandler)) {
return false;
}
- return ((BlazeAndroidBinaryRunConfigurationHandler) handler).getConfigState().mobileInstall()
+ return ((BlazeAndroidBinaryRunConfigurationHandler) handler).getState().mobileInstall()
&& (IncrementalInstallDebugExecutor.EXECUTOR_ID.equals(executorId)
|| IncrementalInstallRunExecutor.EXECUTOR_ID.equals(executorId));
}
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 2bd07cc..a70da60 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
@@ -21,43 +21,34 @@
import com.android.tools.idea.run.ValidationError;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-import com.google.common.collect.Ordering;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler;
-import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandlerEditor;
+import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationValidationUtil;
import com.google.idea.blaze.android.run.binary.instantrun.BlazeAndroidBinaryInstantRunContext;
import com.google.idea.blaze.android.run.binary.mobileinstall.BlazeAndroidBinaryMobileInstallRunContext;
import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner;
import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext;
import com.google.idea.blaze.android.sync.projectstructure.BlazeAndroidProjectStructureSyncer;
-import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
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.projectview.ProjectViewManager;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerEditor;
-import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.configurations.RunProfileState;
-import com.intellij.execution.configurations.RuntimeConfigurationError;
import com.intellij.execution.configurations.RuntimeConfigurationException;
-import com.intellij.execution.configurations.RuntimeConfigurationWarning;
import com.intellij.execution.executors.DefaultRunExecutor;
import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.WriteExternalException;
import icons.AndroidIcons;
import java.util.List;
import javax.swing.Icon;
-import org.jdom.Element;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -68,25 +59,68 @@
*/
public class BlazeAndroidBinaryRunConfigurationHandler
implements BlazeAndroidRunConfigurationHandler {
- private static final Logger LOG =
- Logger.getInstance(BlazeAndroidBinaryRunConfigurationHandler.class);
private final BlazeCommandRunConfiguration configuration;
- private final BlazeAndroidRunConfigurationCommonState commonState;
private final BlazeAndroidBinaryRunConfigurationState configState;
- private final BlazeAndroidRunConfigurationRunner runner;
BlazeAndroidBinaryRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
this.configuration = configuration;
- commonState = new BlazeAndroidRunConfigurationCommonState(ImmutableList.of());
- configState = new BlazeAndroidBinaryRunConfigurationState();
- runner =
- new BlazeAndroidRunConfigurationRunner(
- configuration.getProject(), this, commonState, false, configuration.getUniqueID());
+ configState =
+ new BlazeAndroidBinaryRunConfigurationState(
+ Blaze.buildSystemName(configuration.getProject()));
}
@Override
- public BlazeAndroidRunContext createRunContext(
+ public BlazeAndroidBinaryRunConfigurationState getState() {
+ return configState;
+ }
+
+ @Override
+ public BlazeAndroidRunConfigurationCommonState getCommonState() {
+ return configState.getCommonState();
+ }
+
+ @Override
+ @Nullable
+ public Label getLabel() {
+ TargetExpression target = configuration.getTarget();
+ if (target instanceof Label) {
+ return (Label) target;
+ }
+ return null;
+ }
+
+ @Nullable
+ private Module getModule() {
+ Label target = getLabel();
+ return target != null
+ ? BlazeAndroidProjectStructureSyncer.ensureRunConfigurationModule(
+ configuration.getProject(), target)
+ : null;
+ }
+
+ @Override
+ public BlazeCommandRunConfigurationRunner createRunner(
+ Executor executor, ExecutionEnvironment environment) throws ExecutionException {
+ Project project = environment.getProject();
+
+ Module module = getModule();
+ AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null;
+ ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
+ BlazeAndroidRunConfigurationValidationUtil.validateExecution(module, facet, projectViewSet);
+
+ ImmutableList<String> buildFlags = configState.getBuildFlags(project, projectViewSet);
+ BlazeAndroidRunContext runContext = createRunContext(project, facet, environment, buildFlags);
+
+ return new BlazeAndroidRunConfigurationRunner(
+ module,
+ runContext,
+ getCommonState().getDeployTargetManager(),
+ getCommonState().getDebuggerManager(),
+ configuration.getUniqueID());
+ }
+
+ private BlazeAndroidRunContext createRunContext(
Project project,
AndroidFacet facet,
ExecutionEnvironment env,
@@ -104,120 +138,34 @@
}
@Override
- @Nullable
- public Label getLabel() {
- TargetExpression target = configuration.getTarget();
- if (target instanceof Label) {
- return (Label) target;
- }
- return null;
- }
-
- @Override
- public BlazeAndroidRunConfigurationCommonState getCommonState() {
- return commonState;
- }
-
- @Override
- public BlazeAndroidBinaryRunConfigurationState getConfigState() {
- return configState;
- }
-
- @Nullable
- private Module getModule() {
- Label target = getLabel();
- return target != null
- ? BlazeAndroidProjectStructureSyncer.ensureRunConfigurationModule(
- configuration.getProject(), target)
- : null;
- }
-
- @Override
public final void checkConfiguration() throws RuntimeConfigurationException {
- List<ValidationError> errors = validate();
- if (errors.isEmpty()) {
- return;
- }
- // TODO: Do something with the extra error information? Error count?
- ValidationError topError = Ordering.natural().max(errors);
- if (topError.isFatal()) {
- throw new RuntimeConfigurationError(topError.getMessage(), topError.getQuickfix());
- }
- throw new RuntimeConfigurationWarning(topError.getMessage(), topError.getQuickfix());
+ BlazeAndroidRunConfigurationValidationUtil.throwTopConfigurationError(validate());
}
+ /**
+ * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a
+ * warning. We use a separate method for the collection so the compiler prevents us from
+ * accidentally throwing.
+ */
private List<ValidationError> validate() {
List<ValidationError> errors = Lists.newArrayList();
- errors.addAll(runner.validate(getModule()));
- validateLabel(errors);
+ Module module = getModule();
+ errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateModule(module));
+ AndroidFacet facet = null;
+ if (module != null) {
+ facet = AndroidFacet.getInstance(module);
+ errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateFacet(facet, module));
+ }
+ errors.addAll(configState.validate(facet));
+ errors.addAll(
+ BlazeAndroidRunConfigurationValidationUtil.validateLabel(
+ getLabel(), configuration.getProject(), Kind.ANDROID_BINARY));
return errors;
}
- private void validateLabel(List<ValidationError> errors) {
- Project project = configuration.getProject();
- Label target = getLabel();
- Kind kind = Kind.ANDROID_BINARY;
- RuleIdeInfo rule =
- target != null ? RuleFinder.getInstance().ruleForTarget(project, target) : null;
- if (rule == null) {
- errors.add(
- ValidationError.fatal(
- String.format("No existing %s rule selected.", Blaze.buildSystemName(project))));
- } else if (!rule.kindIsOneOf(kind)) {
- errors.add(
- ValidationError.fatal(
- String.format(
- "Selected %s rule is not %s", Blaze.buildSystemName(project), kind.toString())));
- }
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- commonState.readExternal(element);
- runner.readExternal(element);
- configState.readExternal(element);
- }
-
- @Override
- public void writeExternal(Element element) throws WriteExternalException {
- commonState.writeExternal(element);
- runner.writeExternal(element);
- configState.writeExternal(element);
- }
-
- @Override
- public BlazeAndroidBinaryRunConfigurationHandler cloneFor(
- BlazeCommandRunConfiguration configuration) {
- final Element element = new Element("dummy");
- try {
- writeExternal(element);
- final BlazeAndroidBinaryRunConfigurationHandler handler =
- new BlazeAndroidBinaryRunConfigurationHandler(configuration);
- handler.readExternal(element);
- return handler;
- } catch (InvalidDataException | WriteExternalException e) {
- LOG.error(e);
- return null;
- }
- }
-
@Override
@Nullable
- public final RunProfileState getState(
- @NotNull final Executor executor, @NotNull ExecutionEnvironment env)
- throws ExecutionException {
- final Module module = getModule();
- return runner.getState(module, executor, env);
- }
-
- @Override
- public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
- return runner.executeBuild(environment);
- }
-
- @Override
- @Nullable
- public String suggestedName() {
+ public String suggestedName(BlazeCommandRunConfiguration configuration) {
Label target = getLabel();
if (target == null) {
return null;
@@ -227,11 +175,6 @@
}
@Override
- public boolean isGeneratedName(boolean hasGeneratedFlag) {
- return Comparing.equal(configuration.getName(), suggestedName());
- }
-
- @Override
@Nullable
public String getCommandName() {
return null;
@@ -267,11 +210,4 @@
? AndroidIcons.RunIcons.Replay
: AndroidIcons.RunIcons.DebugReattach;
}
-
- @Override
- public BlazeCommandRunConfigurationHandlerEditor getHandlerEditor() {
- Project project = configuration.getProject();
- return new BlazeAndroidRunConfigurationHandlerEditor(
- project, new BlazeAndroidBinaryRunConfigurationStateEditor(project));
- }
}
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 aab1abc..e657124 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
@@ -15,18 +15,26 @@
*/
package com.google.idea.blaze.android.run.binary;
+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.BlazeAndroidRunConfigurationState;
+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;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
+import java.util.List;
import java.util.Map;
+import javax.annotation.Nullable;
import org.jdom.Element;
+import org.jetbrains.android.facet.AndroidFacet;
/** State specific to the android binary run configuration. */
-public final class BlazeAndroidBinaryRunConfigurationState
- implements BlazeAndroidRunConfigurationState {
+public final class BlazeAndroidBinaryRunConfigurationState implements RunConfigurationState {
public static final String LAUNCH_DEFAULT_ACTIVITY = "default_activity";
public static final String LAUNCH_SPECIFIC_ACTIVITY = "specific_activity";
public static final String DO_NOTHING = "do_nothing";
@@ -51,6 +59,16 @@
private String activityClass = "";
private String mode = LAUNCH_DEFAULT_ACTIVITY;
+ private final BlazeAndroidRunConfigurationCommonState commonState;
+
+ BlazeAndroidBinaryRunConfigurationState(String buildSystemName) {
+ commonState = new BlazeAndroidRunConfigurationCommonState(buildSystemName, false);
+ }
+
+ public BlazeAndroidRunConfigurationCommonState getCommonState() {
+ return commonState;
+ }
+
boolean mobileInstall() {
return mobileInstall;
}
@@ -115,8 +133,22 @@
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.
+ */
+ public List<ValidationError> validate(@Nullable AndroidFacet facet) {
+ return commonState.validate(facet);
+ }
+
@Override
public void readExternal(Element element) throws InvalidDataException {
+ commonState.readExternal(element);
+
setDeepLink(Strings.nullToEmpty(element.getAttributeValue(DEEP_LINK)));
setActivityClass(Strings.nullToEmpty(element.getAttributeValue(ACTIVITY_CLASS)));
setMode(Strings.nullToEmpty(element.getAttributeValue(MODE)));
@@ -156,6 +188,8 @@
@Override
public void writeExternal(Element element) throws WriteExternalException {
+ commonState.writeExternal(element);
+
element.setAttribute(DEEP_LINK, deepLink);
element.setAttribute(ACTIVITY_CLASS, activityClass);
element.setAttribute(MODE, mode);
@@ -166,6 +200,8 @@
if (userId != null) {
element.setAttribute(USER_ID_ATTR, Integer.toString(userId));
+ } else {
+ element.removeAttribute(USER_ID_ATTR);
}
}
@@ -179,4 +215,10 @@
}
return result;
}
+
+ @Override
+ public RunConfigurationStateEditor getEditor(Project project) {
+ return new BlazeAndroidBinaryRunConfigurationStateEditor(
+ commonState.getEditor(project), project);
+ }
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationStateEditor.java b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationStateEditor.java
index ddcbf9a..c7fbff6 100644
--- a/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationStateEditor.java
+++ b/aswb/src/com/google/idea/blaze/android/run/binary/BlazeAndroidBinaryRunConfigurationStateEditor.java
@@ -16,10 +16,11 @@
package com.google.idea.blaze.android.run.binary;
import com.android.tools.idea.run.activity.ActivityLocatorUtils;
-import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationState;
-import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationStateEditor;
import com.google.idea.blaze.android.run.binary.instantrun.InstantRunExperiment;
+import com.google.idea.blaze.base.run.state.RunConfigurationState;
+import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.google.idea.blaze.base.ui.IntegerTextField;
+import com.google.idea.blaze.base.ui.UiUtil;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
@@ -40,7 +41,6 @@
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import java.awt.Color;
-import java.awt.Component;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
@@ -50,26 +50,25 @@
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
+import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.TitledBorder;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidUtils;
-import org.jetbrains.annotations.Nullable;
/**
* The part of the Blaze Android Binary handler editor that allows the user to pick an activity to
* launch. Patterned after {@link org.jetbrains.android.run.ApplicationRunParameters}.
*/
-class BlazeAndroidBinaryRunConfigurationStateEditor
- implements BlazeAndroidRunConfigurationStateEditor {
+class BlazeAndroidBinaryRunConfigurationStateEditor implements RunConfigurationStateEditor {
public static final Key<BlazeAndroidBinaryRunConfigurationStateEditor>
ACTIVITY_CLASS_TEXT_FIELD_KEY = Key.create("BlazeActivityClassTextField");
- private final Project project;
+ private final RunConfigurationStateEditor commonStateEditor;
- @Nullable private JPanel panel;
+ private JPanel panel;
private ComponentWithBrowseButton<EditorTextField> activityField;
private JRadioButton launchNothingButton;
private JRadioButton launchDefaultButton;
@@ -81,10 +80,10 @@
private JLabel userIdLabel;
private IntegerTextField userIdField;
- BlazeAndroidBinaryRunConfigurationStateEditor(Project project) {
- this.project = project;
-
- setupUI();
+ BlazeAndroidBinaryRunConfigurationStateEditor(
+ RunConfigurationStateEditor commonStateEditor, Project project) {
+ this.commonStateEditor = commonStateEditor;
+ setupUI(project);
userIdField.setMinValue(0);
activityField.addActionListener(
@@ -134,7 +133,7 @@
instantRunCheckBox.setVisible(InstantRunExperiment.INSTANT_RUN_ENABLED.getValue());
- /** Only one of mobile-install and instant run can be selected at any one time */
+ /* Only one of mobile-install and instant run can be selected at any one time */
mobileInstallCheckBox.addActionListener(
e -> {
if (mobileInstallCheckBox.isSelected()) {
@@ -158,16 +157,13 @@
}
@Override
- public void resetEditorFrom(BlazeAndroidRunConfigurationState state) {
- BlazeAndroidBinaryRunConfigurationState configState =
- (BlazeAndroidBinaryRunConfigurationState) state;
+ public void resetEditorFrom(RunConfigurationState genericState) {
+ BlazeAndroidBinaryRunConfigurationState state =
+ (BlazeAndroidBinaryRunConfigurationState) genericState;
+ commonStateEditor.resetEditorFrom(state.getCommonState());
boolean launchSpecificActivity =
- configState
- .getMode()
- .equals(BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY);
- if (configState
- .getMode()
- .equals(BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY)) {
+ state.getMode().equals(BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY);
+ if (state.getMode().equals(BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY)) {
launchDefaultButton.setSelected(true);
} else if (launchSpecificActivity) {
launchCustomButton.setSelected(true);
@@ -176,17 +172,17 @@
}
activityField.setEnabled(launchSpecificActivity);
if (launchSpecificActivity) {
- activityField.getChildComponent().setText(configState.getActivityClass());
+ activityField.getChildComponent().setText(state.getActivityClass());
}
- mobileInstallCheckBox.setSelected(configState.mobileInstall());
- splitApksCheckBox.setSelected(configState.useSplitApksIfPossible());
- instantRunCheckBox.setSelected(configState.instantRun());
- useWorkProfileIfPresentCheckBox.setSelected(configState.useWorkProfileIfPresent());
+ mobileInstallCheckBox.setSelected(state.mobileInstall());
+ splitApksCheckBox.setSelected(state.useSplitApksIfPossible());
+ instantRunCheckBox.setSelected(state.instantRun());
+ useWorkProfileIfPresentCheckBox.setSelected(state.useWorkProfileIfPresent());
- userIdField.setValue(configState.getUserId());
- setUserIdEnabled(!configState.useWorkProfileIfPresent());
- splitApksCheckBox.setVisible(configState.mobileInstall());
+ userIdField.setValue(state.getUserId());
+ setUserIdEnabled(!state.useWorkProfileIfPresent());
+ splitApksCheckBox.setVisible(state.mobileInstall());
}
private void setUserIdEnabled(boolean enabled) {
@@ -195,30 +191,32 @@
}
@Override
- public Component getComponent() {
- return panel;
+ public void applyEditorTo(RunConfigurationState genericState) {
+ BlazeAndroidBinaryRunConfigurationState state =
+ (BlazeAndroidBinaryRunConfigurationState) genericState;
+ commonStateEditor.applyEditorTo(state.getCommonState());
+
+ state.setUserId((Integer) userIdField.getValue());
+ if (launchDefaultButton.isSelected()) {
+ state.setMode(BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY);
+ } else if (launchCustomButton.isSelected()) {
+ state.setMode(BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY);
+ state.setActivityClass(activityField.getChildComponent().getText());
+ } else {
+ state.setMode(BlazeAndroidBinaryRunConfigurationState.DO_NOTHING);
+ }
+ state.setMobileInstall(mobileInstallCheckBox.isSelected());
+ state.setUseSplitApksIfPossible(splitApksCheckBox.isSelected());
+ state.setInstantRun(instantRunCheckBox.isSelected());
+ state.setUseWorkProfileIfPresent(useWorkProfileIfPresentCheckBox.isSelected());
}
@Override
- public void applyEditorTo(BlazeAndroidRunConfigurationState state) {
- BlazeAndroidBinaryRunConfigurationState configState =
- (BlazeAndroidBinaryRunConfigurationState) state;
- configState.setUserId((Integer) userIdField.getValue());
- if (launchDefaultButton.isSelected()) {
- configState.setMode(BlazeAndroidBinaryRunConfigurationState.LAUNCH_DEFAULT_ACTIVITY);
- } else if (launchCustomButton.isSelected()) {
- configState.setMode(BlazeAndroidBinaryRunConfigurationState.LAUNCH_SPECIFIC_ACTIVITY);
- configState.setActivityClass(activityField.getChildComponent().getText());
- } else {
- configState.setMode(BlazeAndroidBinaryRunConfigurationState.DO_NOTHING);
- }
- configState.setMobileInstall(mobileInstallCheckBox.isSelected());
- configState.setUseSplitApksIfPossible(splitApksCheckBox.isSelected());
- configState.setInstantRun(instantRunCheckBox.isSelected());
- configState.setUseWorkProfileIfPresent(useWorkProfileIfPresentCheckBox.isSelected());
+ public JComponent createComponent() {
+ return UiUtil.createBox(commonStateEditor.createComponent(), panel);
}
- private void createUIComponents() {
+ private void createUIComponents(Project project) {
final EditorTextField editorTextField =
new LanguageTextField(PlainTextLanguage.INSTANCE, project, "") {
@Override
@@ -239,8 +237,8 @@
}
/** Initially generated by IntelliJ from a .form file, then checked in as source. */
- private void setupUI() {
- createUIComponents();
+ private void setupUI(Project project) {
+ createUIComponents(project);
panel = new JPanel();
panel.setLayout(new GridLayoutManager(5, 2, new Insets(0, 0, 0, 0), -1, -1));
final JPanel activityPanel = new JPanel();
diff --git a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeAndroidDeployInfo.java b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeAndroidDeployInfo.java
index f3ca382..e5f5ad3 100644
--- a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeAndroidDeployInfo.java
+++ b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeAndroidDeployInfo.java
@@ -83,4 +83,13 @@
.map(artifact -> new File(executionRoot, artifact.getExecRootPath()))
.collect(Collectors.toList());
}
+
+ /** Returns the full list of data dependencies to deploy, if any. */
+ public List<File> getDataToDeploy() {
+ return deployInfo
+ .getDataToDeployList()
+ .stream()
+ .map(artifact -> new File(executionRoot, artifact.getExecRootPath()))
+ .collect(Collectors.toList());
+ }
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java
index a1ef71c..3775550 100644
--- a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java
+++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidDeviceSelector.java
@@ -117,7 +117,8 @@
}
}
- DeployTarget deployTarget = deployTargetManager.getDeployTarget(executor, env, facet);
+ DeployTarget deployTarget =
+ deployTargetManager.getDeployTarget(executor, env, facet, runConfigId);
if (deployTarget == null) {
return null;
}
@@ -138,7 +139,8 @@
String currentExecutor = executor.getId();
if (ourKillLaunchOption.isToBeShown()) {
- String msg, noText;
+ String msg;
+ String noText;
if (previousExecutor.equals(currentExecutor)) {
msg =
String.format(
diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java
index 2916688..102512a 100644
--- a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java
+++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidLaunchTasksProvider.java
@@ -109,7 +109,7 @@
launchOptions,
userId,
debuggerManager.getAndroidDebugger(),
- debuggerManager.getAndroidDebuggerState(),
+ debuggerManager.getAndroidDebuggerState(project),
processHandlerLaunchStatus);
if (appLaunchTask != null) {
launchTasks.add(appLaunchTask);
@@ -159,7 +159,7 @@
}
AndroidDebugger androidDebugger = debuggerManager.getAndroidDebugger();
- AndroidDebuggerState androidDebuggerState = debuggerManager.getAndroidDebuggerState();
+ AndroidDebuggerState androidDebuggerState = debuggerManager.getAndroidDebuggerState(project);
if (androidDebugger == null || androidDebuggerState == null) {
return null;
diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationDebuggerManager.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationDebuggerManager.java
index d51f14a..0b429a1 100644
--- a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationDebuggerManager.java
+++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationDebuggerManager.java
@@ -38,20 +38,18 @@
/** Manages android debugger state for the run configurations. */
public class BlazeAndroidRunConfigurationDebuggerManager implements JDOMExternalizable {
- private final Project project;
private final Map<String, AndroidDebuggerState> androidDebuggerStates = Maps.newHashMap();
private final BlazeAndroidRunConfigurationCommonState commonState;
- BlazeAndroidRunConfigurationDebuggerManager(
- Project project, BlazeAndroidRunConfigurationCommonState commonState) {
- this.project = project;
+ public BlazeAndroidRunConfigurationDebuggerManager(
+ BlazeAndroidRunConfigurationCommonState commonState) {
this.commonState = commonState;
for (AndroidDebugger androidDebugger : getAndroidDebuggers()) {
this.androidDebuggerStates.put(androidDebugger.getId(), androidDebugger.createState());
}
}
- List<ValidationError> validate(AndroidFacet facet) {
+ public List<ValidationError> validate(AndroidFacet facet) {
// All of the AndroidDebuggerState classes implement a validate that
// either does nothing or is specific to gradle so there is no point
// in calling validate on our AndroidDebuggerState.
@@ -70,7 +68,7 @@
}
@Nullable
- final <T extends AndroidDebuggerState> T getAndroidDebuggerState() {
+ final <T extends AndroidDebuggerState> T getAndroidDebuggerState(Project project) {
T androidDebuggerState = getAndroidDebuggerState(getDebuggerID());
// Set our working directory to our workspace root for native debugging.
if (androidDebuggerState instanceof NativeAndroidDebuggerState) {
diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationDeployTargetManager.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationDeployTargetManager.java
index 306bec4..44a8eb3 100644
--- a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationDeployTargetManager.java
+++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationDeployTargetManager.java
@@ -40,13 +40,11 @@
public class BlazeAndroidRunConfigurationDeployTargetManager implements JDOMExternalizable {
private static final String TARGET_SELECTION_MODE = TargetSelectionMode.SHOW_DIALOG.name();
- private final int runConfigId;
private final boolean isAndroidTest;
private final List<DeployTargetProvider> deployTargetProviders;
private final Map<String, DeployTargetState> deployTargetStates;
- BlazeAndroidRunConfigurationDeployTargetManager(int runConfigId, boolean isAndroidTest) {
- this.runConfigId = runConfigId;
+ public BlazeAndroidRunConfigurationDeployTargetManager(boolean isAndroidTest) {
this.isAndroidTest = isAndroidTest;
this.deployTargetProviders = DeployTargetProvider.getProviders();
@@ -57,12 +55,13 @@
this.deployTargetStates = builder.build();
}
- List<ValidationError> validate(AndroidFacet facet) {
+ public List<ValidationError> validate(AndroidFacet facet) {
return getCurrentDeployTargetState().validate(facet);
}
@Nullable
- DeployTarget getDeployTarget(Executor executor, ExecutionEnvironment env, AndroidFacet facet)
+ DeployTarget getDeployTarget(
+ Executor executor, ExecutionEnvironment env, AndroidFacet facet, int runConfigId)
throws ExecutionException {
DeployTargetProvider currentTargetProvider = getCurrentDeployTargetProvider();
diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java
index e0cef2a..76e3bfc 100644
--- a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java
+++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeAndroidRunConfigurationRunner.java
@@ -16,7 +16,6 @@
package com.google.idea.blaze.android.run.runner;
-import static com.android.tools.idea.gradle.util.Projects.requiredAndroidModelMissing;
import static org.jetbrains.android.actions.RunAndroidAvdManagerAction.getName;
import com.android.ddmlib.IDevice;
@@ -28,22 +27,15 @@
import com.android.tools.idea.run.LaunchInfo;
import com.android.tools.idea.run.LaunchOptions;
import com.android.tools.idea.run.LaunchTaskRunner;
-import com.android.tools.idea.run.ValidationError;
import com.android.tools.idea.run.editor.DeployTarget;
import com.android.tools.idea.run.editor.DeployTargetState;
import com.android.tools.idea.run.tasks.LaunchTasksProvider;
import com.android.tools.idea.run.util.LaunchUtils;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
-import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState;
-import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler;
-import com.google.idea.blaze.base.command.BlazeFlags;
import com.google.idea.blaze.base.experiments.ExperimentScope;
import com.google.idea.blaze.base.metrics.Action;
-import com.google.idea.blaze.base.projectview.ProjectViewManager;
-import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
import com.google.idea.blaze.base.scope.Scope;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.scope.scopes.BlazeConsoleScope;
@@ -65,12 +57,7 @@
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.WriteExternalException;
-import java.util.List;
-import org.jdom.Element;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.sdk.AndroidSdkUtils;
import org.jetbrains.android.util.AndroidBundle;
@@ -78,128 +65,50 @@
import org.jetbrains.annotations.Nullable;
/**
- * Supports the entire run configuration flow. Used by both android_binary and android_test.
+ * Supports the execution. Used by both android_binary and android_test.
*
- * <p>Does any verification necessary, builds the APK and installs it, launches and debug tasks,
- * etc.
+ * <p>Builds the APK and installs it, launches and debug tasks, etc.
*
* <p>Any indirection between android_binary/android_test, mobile-install, InstantRun etc. should
* come via the strategy class.
*/
-public final class BlazeAndroidRunConfigurationRunner implements JDOMExternalizable {
+public final class BlazeAndroidRunConfigurationRunner
+ implements BlazeCommandRunConfigurationRunner {
private static final Logger LOG = Logger.getInstance(BlazeAndroidRunConfigurationRunner.class);
- private static final String SYNC_FAILED_ERR_MSG =
- "Project state is invalid. Please sync and try your action again.";
-
- public static final Key<BlazeAndroidRunContext> RUN_CONTEXT_KEY = Key.create("blaze.run.context");
- public static final Key<BlazeAndroidDeviceSelector.DeviceSession> DEVICE_SESSION_KEY =
+ private static final Key<BlazeAndroidRunContext> RUN_CONTEXT_KEY =
+ Key.create("blaze.run.context");
+ private static final Key<BlazeAndroidDeviceSelector.DeviceSession> DEVICE_SESSION_KEY =
Key.create("blaze.device.session");
- // We need to split "-c dbg" into two flags because we pass flags
- // as a list of strings to the command line executor and we need blaze
- // to see -c and dbg as two separate entities, not one.
- private static final ImmutableList<String> NATIVE_DEBUG_FLAGS =
- ImmutableList.of("--fission=no", "-c", "dbg");
-
- private final Project project;
-
- private final BlazeAndroidRunConfigurationHandler runConfigurationHandler;
-
- private final BlazeAndroidRunConfigurationCommonState commonState;
-
+ private final Module module;
+ private final BlazeAndroidRunContext runContext;
+ private final BlazeAndroidRunConfigurationDeployTargetManager deployTargetManager;
+ private final BlazeAndroidRunConfigurationDebuggerManager debuggerManager;
private final int runConfigId;
- private final BlazeAndroidRunConfigurationDeployTargetManager deployTargetManager;
-
- private final BlazeAndroidRunConfigurationDebuggerManager debuggerManager;
-
public BlazeAndroidRunConfigurationRunner(
- Project project,
- BlazeAndroidRunConfigurationHandler runConfigurationHandler,
- BlazeAndroidRunConfigurationCommonState commonState,
- boolean isAndroidTest,
+ Module module,
+ BlazeAndroidRunContext runContext,
+ BlazeAndroidRunConfigurationDeployTargetManager deployTargetManager,
+ BlazeAndroidRunConfigurationDebuggerManager debuggerManager,
int runConfigId) {
- this.project = project;
- this.runConfigurationHandler = runConfigurationHandler;
- this.commonState = commonState;
+ this.module = module;
+ this.runContext = runContext;
+ this.deployTargetManager = deployTargetManager;
+ this.debuggerManager = debuggerManager;
this.runConfigId = runConfigId;
- this.deployTargetManager =
- new BlazeAndroidRunConfigurationDeployTargetManager(runConfigId, isAndroidTest);
- this.debuggerManager = new BlazeAndroidRunConfigurationDebuggerManager(project, commonState);
}
- private ImmutableList<String> getBuildFlags(Project project, ProjectViewSet projectViewSet) {
- return ImmutableList.<String>builder()
- .addAll(BlazeFlags.buildFlags(project, projectViewSet))
- .addAll(commonState.getUserFlags())
- .addAll(getNativeDebuggerFlags())
- .build();
- }
-
- public ImmutableList<String> getNativeDebuggerFlags() {
- return commonState.isNativeDebuggingEnabled() ? NATIVE_DEBUG_FLAGS : ImmutableList.of();
- }
-
- /**
- * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a
- * warning. We use a separate method for the collection so the compiler prevents us from
- * accidentally throwing.
- */
- public List<ValidationError> validate(@Nullable Module module) {
- List<ValidationError> errors = Lists.newArrayList();
- if (module == null) {
- errors.add(
- ValidationError.fatal(
- "No run configuration module found. Have you successfully synced your project?"));
- return errors;
- }
-
- if (runConfigurationHandler.getLabel() == null) {
- errors.add(ValidationError.fatal("No target selected"));
- return errors;
- }
-
- final Project project = module.getProject();
- if (requiredAndroidModelMissing(project)) {
- errors.add(ValidationError.fatal(SYNC_FAILED_ERR_MSG));
- }
-
- AndroidFacet facet = AndroidFacet.getInstance(module);
- if (facet == null) {
- // Can't proceed.
- return ImmutableList.of(
- ValidationError.fatal(AndroidBundle.message("no.facet.error", module.getName())));
- }
-
- if (facet.getConfiguration().getAndroidPlatform() == null) {
- errors.add(ValidationError.fatal(AndroidBundle.message("select.platform.error")));
- }
-
- errors.addAll(deployTargetManager.validate(facet));
- errors.addAll(debuggerManager.validate(facet));
-
- return errors;
- }
-
+ @Override
@Nullable
- public final RunProfileState getState(
- Module module, final Executor executor, ExecutionEnvironment env) throws ExecutionException {
+ public final RunProfileState getRunProfileState(final Executor executor, ExecutionEnvironment env)
+ throws ExecutionException {
- assert module != null : "Enforced by fatal validation check in checkConfiguration.";
final AndroidFacet facet = AndroidFacet.getInstance(module);
- assert facet != null : "Enforced by fatal validation check in checkConfiguration.";
- Project project = env.getProject();
-
- ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
- if (projectViewSet == null) {
- throw new ExecutionException("Could not load project view. Please resync project");
- }
- ImmutableList<String> buildFlags = getBuildFlags(project, projectViewSet);
-
- BlazeAndroidRunContext runContext =
- runConfigurationHandler.createRunContext(project, facet, env, buildFlags);
+ assert facet != null : "Enforced by fatal validation check in createRunner.";
+ final Project project = env.getProject();
runContext.augmentEnvironment(env);
@@ -279,7 +188,9 @@
.setForceStopRunningApp(true);
}
- public boolean executeBuild(ExecutionEnvironment env) {
+ @Override
+ public boolean executeBeforeRunTask(ExecutionEnvironment env) {
+ final Project project = env.getProject();
boolean suppressConsole = BlazeUserSettings.getInstance().getSuppressConsoleForRunAction();
return Scope.root(
context -> {
@@ -400,16 +311,4 @@
return console == null ? null : new DefaultExecutionResult(console, processHandler);
}
}
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- deployTargetManager.readExternal(element);
- debuggerManager.readExternal(element);
- }
-
- @Override
- public void writeExternal(Element element) throws WriteExternalException {
- deployTargetManager.writeExternal(element);
- debuggerManager.writeExternal(element);
- }
}
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 ff1e6b7..f48fd2c 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
@@ -79,12 +79,11 @@
return false;
}
configuration.setTarget(rule.label);
- BlazeAndroidTestRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeAndroidTestRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeAndroidTestRunConfigurationState configState =
+ configuration.getHandlerStateIfType(BlazeAndroidTestRunConfigurationState.class);
+ if (configState == null) {
return false;
}
- BlazeAndroidTestRunConfigurationState configState = handler.getConfigState();
configState.setTestingType(AndroidTestRunConfiguration.TEST_CLASS);
configState.setClassName(testClass.getQualifiedName());
configuration.setGeneratedName();
@@ -122,12 +121,11 @@
private static boolean checkIfAttributesAreTheSame(
BlazeCommandRunConfiguration configuration, PsiClass testClass) {
- BlazeAndroidTestRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeAndroidTestRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeAndroidTestRunConfigurationState configState =
+ configuration.getHandlerStateIfType(BlazeAndroidTestRunConfigurationState.class);
+ if (configState == null) {
return false;
}
- BlazeAndroidTestRunConfigurationState configState = handler.getConfigState();
if (Strings.isNullOrEmpty(configState.getClassName())) {
return false;
}
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 7f87f1b..4334cd4 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
@@ -79,12 +79,11 @@
return false;
}
configuration.setTarget(rule.label);
- BlazeAndroidTestRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeAndroidTestRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeAndroidTestRunConfigurationState configState =
+ configuration.getHandlerStateIfType(BlazeAndroidTestRunConfigurationState.class);
+ if (configState == null) {
return false;
}
- BlazeAndroidTestRunConfigurationState configState = handler.getConfigState();
configState.setTestingType(AndroidTestRunConfiguration.TEST_METHOD);
configState.setClassName(containingClass.getQualifiedName());
configState.setMethodName(psiMethod.getName());
@@ -120,12 +119,11 @@
private static boolean checkIfAttributesAreTheSame(
BlazeCommandRunConfiguration configuration, PsiMethod testMethod) {
- BlazeAndroidTestRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeAndroidTestRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeAndroidTestRunConfigurationState configState =
+ configuration.getHandlerStateIfType(BlazeAndroidTestRunConfigurationState.class);
+ if (configState == null) {
return false;
}
- BlazeAndroidTestRunConfigurationState configState = handler.getConfigState();
if (Strings.isNullOrEmpty(configState.getClassName())
|| Strings.isNullOrEmpty(configState.getMethodName())) {
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 885a8ae..d63ea0c 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
@@ -18,42 +18,32 @@
import com.android.tools.idea.run.ValidationError;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
-import com.google.common.collect.Ordering;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationCommonState;
import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandler;
-import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationHandlerEditor;
+import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationValidationUtil;
import com.google.idea.blaze.android.run.runner.BlazeAndroidRunConfigurationRunner;
import com.google.idea.blaze.android.run.runner.BlazeAndroidRunContext;
import com.google.idea.blaze.android.sync.projectstructure.BlazeAndroidProjectStructureSyncer;
-import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
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.projectview.ProjectViewManager;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerEditor;
-import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.configurations.RunProfileState;
-import com.intellij.execution.configurations.RuntimeConfigurationError;
import com.intellij.execution.configurations.RuntimeConfigurationException;
-import com.intellij.execution.configurations.RuntimeConfigurationWarning;
import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.WriteExternalException;
import java.util.List;
import javax.swing.Icon;
-import org.jdom.Element;
import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -62,31 +52,25 @@
*/
public class BlazeAndroidTestRunConfigurationHandler
implements BlazeAndroidRunConfigurationHandler {
- private static final Logger LOG =
- Logger.getInstance(BlazeAndroidTestRunConfigurationHandler.class);
private final BlazeCommandRunConfiguration configuration;
- private final BlazeAndroidRunConfigurationCommonState commonState;
private final BlazeAndroidTestRunConfigurationState configState;
- private final BlazeAndroidRunConfigurationRunner runner;
BlazeAndroidTestRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
this.configuration = configuration;
- commonState = new BlazeAndroidRunConfigurationCommonState(ImmutableList.of());
- configState = new BlazeAndroidTestRunConfigurationState();
- runner =
- new BlazeAndroidRunConfigurationRunner(
- configuration.getProject(), this, commonState, true, configuration.getUniqueID());
+ configState =
+ new BlazeAndroidTestRunConfigurationState(
+ Blaze.buildSystemName(configuration.getProject()));
}
@Override
- public BlazeAndroidRunContext createRunContext(
- Project project,
- AndroidFacet facet,
- ExecutionEnvironment env,
- ImmutableList<String> buildFlags) {
- return new BlazeAndroidTestRunContext(
- project, facet, configuration, env, configState, getLabel(), buildFlags);
+ public BlazeAndroidTestRunConfigurationState getState() {
+ return configState;
+ }
+
+ @Override
+ public BlazeAndroidRunConfigurationCommonState getCommonState() {
+ return configState.getCommonState();
}
@Override
@@ -99,16 +83,6 @@
return null;
}
- @Override
- public BlazeAndroidRunConfigurationCommonState getCommonState() {
- return commonState;
- }
-
- @Override
- public BlazeAndroidTestRunConfigurationState getConfigState() {
- return configState;
- }
-
@Nullable
private Module getModule() {
Label target = getLabel();
@@ -119,96 +93,70 @@
}
@Override
- public final void checkConfiguration() throws RuntimeConfigurationException {
- List<ValidationError> errors = validate();
- if (errors.isEmpty()) {
- return;
- }
- // TODO: Do something with the extra error information? Error count?
- ValidationError topError = Ordering.natural().max(errors);
- if (topError.isFatal()) {
- throw new RuntimeConfigurationError(topError.getMessage(), topError.getQuickfix());
- }
- throw new RuntimeConfigurationWarning(topError.getMessage(), topError.getQuickfix());
+ public BlazeCommandRunConfigurationRunner createRunner(
+ Executor executor, ExecutionEnvironment environment) throws ExecutionException {
+ Project project = environment.getProject();
+
+ Module module = getModule();
+ AndroidFacet facet = module != null ? AndroidFacet.getInstance(module) : null;
+ ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
+ BlazeAndroidRunConfigurationValidationUtil.validateExecution(module, facet, projectViewSet);
+
+ ImmutableList<String> buildFlags = configState.getBuildFlags(project, projectViewSet);
+ BlazeAndroidRunContext runContext = createRunContext(project, facet, environment, buildFlags);
+
+ return new BlazeAndroidRunConfigurationRunner(
+ module,
+ runContext,
+ getCommonState().getDeployTargetManager(),
+ getCommonState().getDebuggerManager(),
+ configuration.getUniqueID());
}
+ private BlazeAndroidRunContext createRunContext(
+ Project project,
+ AndroidFacet facet,
+ ExecutionEnvironment env,
+ ImmutableList<String> buildFlags) {
+ return new BlazeAndroidTestRunContext(
+ project, facet, configuration, env, configState, getLabel(), buildFlags);
+ }
+
+ @Override
+ public final void checkConfiguration() throws RuntimeConfigurationException {
+ BlazeAndroidRunConfigurationValidationUtil.throwTopConfigurationError(validate());
+ }
+
+ /**
+ * We collect errors rather than throwing to avoid missing fatal errors by exiting early for a
+ * warning. We use a separate method for the collection so the compiler prevents us from
+ * accidentally throwing.
+ */
private List<ValidationError> validate() {
List<ValidationError> errors = Lists.newArrayList();
- errors.addAll(runner.validate(getModule()));
- validateLabel(errors);
+ Module module = getModule();
+ errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateModule(module));
+ AndroidFacet facet = null;
+ if (module != null) {
+ facet = AndroidFacet.getInstance(module);
+ errors.addAll(BlazeAndroidRunConfigurationValidationUtil.validateFacet(facet, module));
+ }
+ errors.addAll(configState.validate(facet));
+ errors.addAll(
+ BlazeAndroidRunConfigurationValidationUtil.validateLabel(
+ getLabel(), configuration.getProject(), Kind.ANDROID_TEST));
return errors;
}
- private void validateLabel(List<ValidationError> errors) {
- Project project = configuration.getProject();
- Label target = getLabel();
- Kind kind = Kind.ANDROID_TEST;
- RuleIdeInfo rule =
- target != null ? RuleFinder.getInstance().ruleForTarget(project, target) : null;
- if (rule == null) {
- errors.add(
- ValidationError.fatal(
- String.format("No existing %s rule selected.", Blaze.buildSystemName(project))));
- } else if (!rule.kindIsOneOf(kind)) {
- errors.add(
- ValidationError.fatal(
- String.format(
- "Selected %s rule is not %s", Blaze.buildSystemName(project), kind.toString())));
- }
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- commonState.readExternal(element);
- runner.readExternal(element);
- configState.readExternal(element);
- }
-
- @Override
- public void writeExternal(Element element) throws WriteExternalException {
- commonState.writeExternal(element);
- runner.writeExternal(element);
- configState.writeExternal(element);
- }
-
- @Override
- public BlazeAndroidTestRunConfigurationHandler cloneFor(
- BlazeCommandRunConfiguration configuration) {
- final Element element = new Element("dummy");
- try {
- writeExternal(element);
- final BlazeAndroidTestRunConfigurationHandler handler =
- new BlazeAndroidTestRunConfigurationHandler(configuration);
- handler.readExternal(element);
- return handler;
- } catch (InvalidDataException | WriteExternalException e) {
- LOG.error(e);
- return null;
- }
- }
-
@Override
@Nullable
- public final RunProfileState getState(
- @NotNull final Executor executor, @NotNull ExecutionEnvironment env)
- throws ExecutionException {
- final Module module = getModule();
- return runner.getState(module, executor, env);
- }
-
- @Override
- public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
- return runner.executeBuild(environment);
- }
-
- @Override
- @Nullable
- public String suggestedName() {
+ public String suggestedName(BlazeCommandRunConfiguration configuration) {
Label target = getLabel();
if (target == null) {
return null;
}
- BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration);
+ BlazeConfigurationNameBuilder nameBuilder =
+ new BlazeConfigurationNameBuilder(this.configuration);
boolean isClassTest =
configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_CLASS;
@@ -229,22 +177,6 @@
}
@Override
- public boolean isGeneratedName(boolean hasGeneratedFlag) {
- final String name = configuration.getName();
-
- if ((configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_CLASS
- || configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_METHOD)
- && (configState.getClassName() == null || configState.getClassName().length() == 0)) {
- return JavaExecutionUtil.isNewName(name);
- }
- if (configState.getTestingType() == BlazeAndroidTestRunConfigurationState.TEST_METHOD
- && (configState.getMethodName() == null || configState.getMethodName().length() == 0)) {
- return JavaExecutionUtil.isNewName(name);
- }
- return Comparing.equal(name, suggestedName());
- }
-
- @Override
@Nullable
public String getCommandName() {
return "test";
@@ -260,11 +192,4 @@
public Icon getExecutorIcon(RunConfiguration configuration, Executor executor) {
return null;
}
-
- @Override
- public BlazeCommandRunConfigurationHandlerEditor getHandlerEditor() {
- Project project = configuration.getProject();
- return new BlazeAndroidRunConfigurationHandlerEditor(
- project, new BlazeAndroidTestRunConfigurationStateEditor(project));
- }
}
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 9f05bc5..62fcbb3 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
@@ -15,17 +15,26 @@
*/
package com.google.idea.blaze.android.run.test;
+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.BlazeAndroidRunConfigurationState;
+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;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
+import java.util.List;
import java.util.Map;
+import javax.annotation.Nullable;
import org.jdom.Element;
+import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.Contract;
/** State specific for the android test configuration. */
-final class BlazeAndroidTestRunConfigurationState implements BlazeAndroidRunConfigurationState {
+final class BlazeAndroidTestRunConfigurationState implements RunConfigurationState {
private static final String RUN_THROUGH_BLAZE_ATTR = "blaze-run-through-blaze";
@@ -47,7 +56,7 @@
private static final String EXTRA_OPTIONS = "EXTRA_OPTIONS";
private int testingType = TEST_ALL_IN_MODULE;
- private String instrumentationRunnerClass;
+ private String instrumentationRunnerClass = "";
private String methodName = "";
private String className = "";
private String packageName = "";
@@ -56,10 +65,14 @@
// Whether to delegate to 'blaze test'.
private boolean runThroughBlaze;
- public BlazeAndroidTestRunConfigurationState() {
- String defaultInstrumentationRunnerClass =
- InstrumentationRunnerProvider.getDefaultInstrumentationRunnerClass();
- instrumentationRunnerClass = Strings.nullToEmpty(defaultInstrumentationRunnerClass);
+ private final BlazeAndroidRunConfigurationCommonState commonState;
+
+ public BlazeAndroidTestRunConfigurationState(String buildSystemName) {
+ commonState = new BlazeAndroidRunConfigurationCommonState(buildSystemName, true);
+ }
+
+ public BlazeAndroidRunConfigurationCommonState getCommonState() {
+ return commonState;
}
@Contract(pure = true)
@@ -119,8 +132,22 @@
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.
+ */
+ public List<ValidationError> validate(@Nullable AndroidFacet facet) {
+ return commonState.validate(facet);
+ }
+
@Override
public void readExternal(Element element) throws InvalidDataException {
+ commonState.readExternal(element);
+
String testingTypeAttribute = element.getAttributeValue(TESTING_TYPE);
if (!Strings.isNullOrEmpty(testingTypeAttribute)) {
testingType = Integer.parseInt(testingTypeAttribute);
@@ -164,6 +191,8 @@
@Override
public void writeExternal(Element element) throws WriteExternalException {
+ commonState.writeExternal(element);
+
element.setAttribute(RUN_THROUGH_BLAZE_ATTR, Boolean.toString(runThroughBlaze));
element.setAttribute(TESTING_TYPE, Integer.toString(testingType));
element.setAttribute(INSTRUMENTATION_RUNNER_CLASS, instrumentationRunnerClass);
@@ -183,4 +212,9 @@
}
return result;
}
+
+ @Override
+ public RunConfigurationStateEditor getEditor(Project project) {
+ return new BlazeAndroidTestRunConfigurationStateEditor(commonState.getEditor(project), project);
+ }
}
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 d03f883..eb8293a 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
@@ -21,9 +21,10 @@
import static com.android.tools.idea.run.testing.AndroidTestRunConfiguration.TEST_CLASS;
import static com.android.tools.idea.run.testing.AndroidTestRunConfiguration.TEST_METHOD;
-import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationState;
-import com.google.idea.blaze.android.run.BlazeAndroidRunConfigurationStateEditor;
+import com.google.idea.blaze.base.run.state.RunConfigurationState;
+import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.ui.UiUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.ui.EditorTextField;
@@ -31,7 +32,6 @@
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
-import java.awt.Component;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -39,6 +39,7 @@
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
+import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
@@ -47,8 +48,9 @@
* The part of the Blaze Android Test handler editor that allows the user to pick test filters.
* Forked from {@link org.jetbrains.android.run.testing.TestRunParameters}.
*/
-class BlazeAndroidTestRunConfigurationStateEditor
- implements BlazeAndroidRunConfigurationStateEditor {
+class BlazeAndroidTestRunConfigurationStateEditor implements RunConfigurationStateEditor {
+ private final RunConfigurationStateEditor commonStateEditor;
+
private JRadioButton allInPackageButton;
private JRadioButton classButton;
private JRadioButton testMethodButton;
@@ -62,7 +64,9 @@
private JCheckBox runThroughBlazeTestCheckBox;
private final JRadioButton[] testingType2RadioButton = new JRadioButton[4];
- BlazeAndroidTestRunConfigurationStateEditor(Project project) {
+ BlazeAndroidTestRunConfigurationStateEditor(
+ RunConfigurationStateEditor commonStateEditor, Project project) {
+ this.commonStateEditor = commonStateEditor;
setupUI(project);
packageComponent.setComponent(new EditorTextField());
@@ -441,33 +445,37 @@
}
@Override
- public void applyEditorTo(BlazeAndroidRunConfigurationState state) {
- BlazeAndroidTestRunConfigurationState configState =
- (BlazeAndroidTestRunConfigurationState) state;
- configState.setRunThroughBlaze(runThroughBlazeTestCheckBox.isSelected());
+ public void applyEditorTo(RunConfigurationState genericState) {
+ BlazeAndroidTestRunConfigurationState state =
+ (BlazeAndroidTestRunConfigurationState) genericState;
+ commonStateEditor.applyEditorTo(state.getCommonState());
- configState.setTestingType(getTestingType());
- configState.setClassName(classComponent.getComponent().getText());
- configState.setMethodName(methodComponent.getComponent().getText());
- configState.setPackageName(packageComponent.getComponent().getText());
- configState.setInstrumentationRunnerClass(runnerComponent.getComponent().getText());
+ state.setRunThroughBlaze(runThroughBlazeTestCheckBox.isSelected());
+
+ state.setTestingType(getTestingType());
+ state.setClassName(classComponent.getComponent().getText());
+ state.setMethodName(methodComponent.getComponent().getText());
+ state.setPackageName(packageComponent.getComponent().getText());
+ state.setInstrumentationRunnerClass(runnerComponent.getComponent().getText());
}
@Override
- public void resetEditorFrom(BlazeAndroidRunConfigurationState state) {
- BlazeAndroidTestRunConfigurationState configState =
- (BlazeAndroidTestRunConfigurationState) state;
- runThroughBlazeTestCheckBox.setSelected(configState.isRunThroughBlaze());
+ public void resetEditorFrom(RunConfigurationState genericState) {
+ BlazeAndroidTestRunConfigurationState state =
+ (BlazeAndroidTestRunConfigurationState) genericState;
+ commonStateEditor.resetEditorFrom(state.getCommonState());
- updateButtonsAndLabelComponents(configState.getTestingType());
- packageComponent.getComponent().setText(configState.getPackageName());
- classComponent.getComponent().setText(configState.getClassName());
- methodComponent.getComponent().setText(configState.getMethodName());
- runnerComponent.getComponent().setText(configState.getInstrumentationRunnerClass());
+ runThroughBlazeTestCheckBox.setSelected(state.isRunThroughBlaze());
+
+ updateButtonsAndLabelComponents(state.getTestingType());
+ packageComponent.getComponent().setText(state.getPackageName());
+ classComponent.getComponent().setText(state.getClassName());
+ methodComponent.getComponent().setText(state.getMethodName());
+ runnerComponent.getComponent().setText(state.getInstrumentationRunnerClass());
}
@Override
- public Component getComponent() {
- return panel;
+ public JComponent createComponent() {
+ return UiUtil.createBox(commonStateEditor.createComponent(), panel);
}
}
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 a12d370..8f2f218 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
@@ -32,6 +32,8 @@
import com.android.tools.idea.run.util.ProcessHandlerLaunchStatus;
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.run.deployinfo.BlazeAndroidDeployInfo;
import com.google.idea.blaze.android.run.deployinfo.BlazeApkProvider;
import com.google.idea.blaze.android.run.runner.BlazeAndroidDeviceSelector;
import com.google.idea.blaze.android.run.runner.BlazeAndroidLaunchTasksProvider;
@@ -130,6 +132,18 @@
@Override
public ImmutableList<LaunchTask> getDeployTasks(IDevice device, LaunchOptions launchOptions)
throws ExecutionException {
+ if (!configState.isRunThroughBlaze()) {
+ BlazeAndroidDeployInfo deployInfo =
+ Futures.get(buildStep.getDeployInfo(), ExecutionException.class);
+ if (!deployInfo.getDataToDeploy().isEmpty()) {
+ throw new ExecutionException(
+ "This test target has data dependencies (defined in the 'data' attribute).\n"
+ + "These can only be installed if the configuration is run through 'blaze test'.\n"
+ + "Check the \"Run through 'blaze test'\" checkbox on your "
+ + "run configuration and try again.");
+ }
+ }
+
Collection<ApkInfo> apks;
try {
apks = apkProvider.getApks(device);
@@ -161,10 +175,13 @@
this,
launchOptions.isDebug());
}
+ BlazeAndroidDeployInfo deployInfo =
+ Futures.get(buildStep.getDeployInfo(), ExecutionException.class);
return StockAndroidTestLaunchTask.getStockTestLaunchTask(
configState,
applicationIdProvider,
launchOptions.isDebug(),
+ deployInfo,
facet,
processHandlerLaunchStatus);
}
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 4ec111f..e17cb97 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
@@ -25,6 +25,7 @@
import com.android.tools.idea.run.tasks.LaunchTask;
import com.android.tools.idea.run.testing.AndroidTestListener;
import com.android.tools.idea.run.util.LaunchStatus;
+import com.google.idea.blaze.android.run.deployinfo.BlazeAndroidDeployInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
@@ -33,21 +34,20 @@
import org.jetbrains.android.dom.manifest.Instrumentation;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.facet.AndroidFacet;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
final class StockAndroidTestLaunchTask implements LaunchTask {
private static final Logger LOG = Logger.getInstance(StockAndroidTestLaunchTask.class);
- @NotNull private final BlazeAndroidTestRunConfigurationState configState;
+ private final BlazeAndroidTestRunConfigurationState configState;
@Nullable private final String instrumentationTestRunner;
- @NotNull private final String testApplicationId;
+ private final String testApplicationId;
private final boolean waitForDebugger;
private StockAndroidTestLaunchTask(
- @NotNull BlazeAndroidTestRunConfigurationState configState,
+ BlazeAndroidTestRunConfigurationState configState,
@Nullable String runner,
- @NotNull String testPackage,
+ String testPackage,
boolean waitForDebugger) {
this.configState = configState;
this.instrumentationTestRunner = runner;
@@ -56,14 +56,15 @@
}
public static LaunchTask getStockTestLaunchTask(
- @NotNull BlazeAndroidTestRunConfigurationState configState,
- @NotNull ApplicationIdProvider applicationIdProvider,
+ BlazeAndroidTestRunConfigurationState configState,
+ ApplicationIdProvider applicationIdProvider,
boolean waitForDebugger,
- @NotNull AndroidFacet facet,
- @NotNull LaunchStatus launchStatus) {
+ BlazeAndroidDeployInfo deployInfo,
+ AndroidFacet facet,
+ LaunchStatus launchStatus) {
String runner =
StringUtil.isEmpty(configState.getInstrumentationRunnerClass())
- ? findInstrumentationRunner(facet)
+ ? findInstrumentationRunner(deployInfo, facet)
: configState.getInstrumentationRunnerClass();
String testPackage;
try {
@@ -81,8 +82,9 @@
}
@Nullable
- private static String findInstrumentationRunner(@NotNull AndroidFacet facet) {
- String runner = getRunnerFromManifest(facet);
+ private static String findInstrumentationRunner(
+ BlazeAndroidDeployInfo deployInfo, AndroidFacet facet) {
+ String runner = getRunnerFromManifest(deployInfo);
// TODO: Resolve direct AndroidGradleModel dep (b/22596984)
AndroidGradleModel androidModel = AndroidGradleModel.get(facet);
@@ -94,23 +96,22 @@
}
}
+ // Fall back to the default runner.
+ if (runner == null) {
+ runner = InstrumentationRunnerProvider.getDefaultInstrumentationRunnerClass();
+ }
+
return runner;
}
@Nullable
- private static String getRunnerFromManifest(@NotNull final AndroidFacet facet) {
+ private static String getRunnerFromManifest(final BlazeAndroidDeployInfo deployInfo) {
if (!ApplicationManager.getApplication().isReadAccessAllowed()) {
return ApplicationManager.getApplication()
- .runReadAction(
- new Computable<String>() {
- @Override
- public String compute() {
- return getRunnerFromManifest(facet);
- }
- });
+ .runReadAction((Computable<String>) () -> getRunnerFromManifest(deployInfo));
}
- Manifest manifest = facet.getManifest();
+ Manifest manifest = deployInfo.getMergedManifest();
if (manifest != null) {
for (Instrumentation instrumentation : manifest.getInstrumentations()) {
if (instrumentation != null) {
@@ -124,7 +125,6 @@
return null;
}
- @NotNull
@Override
public String getDescription() {
return "Launching instrumentation runner";
@@ -137,9 +137,7 @@
@Override
public boolean perform(
- @NotNull IDevice device,
- @NotNull final LaunchStatus launchStatus,
- @NotNull final ConsolePrinter printer) {
+ IDevice device, final LaunchStatus launchStatus, final ConsolePrinter printer) {
printer.stdout("Running tests\n");
final RemoteAndroidTestRunner runner =
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 58f99de..162f693 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.sync.workspace.ArtifactLocationDecoder;
import com.intellij.openapi.project.Project;
import java.io.File;
import java.util.Collection;
@@ -36,7 +37,8 @@
if (syncData.importResult.resourceLibrary == null) {
return;
}
- files.addAll(syncData.importResult.resourceLibrary.sources);
+ ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
+ files.addAll(artifactLocationDecoder.decodeAll(syncData.importResult.resourceLibrary.sources));
}
@Override
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 96df410..ffc3edb 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 = androidRuleIdeInfo.idlJar;
if (idlJar != null) {
- genJars.add(new BlazeJarLibrary(idlJar, rule.label));
+ genJars.add(new BlazeJarLibrary(idlJar, rule.key));
}
if (BlazeAndroidWorkspaceImporter.shouldGenerateResources(androidRuleIdeInfo)
@@ -60,7 +60,7 @@
if (!discardResourceJar) {
LibraryArtifact resourceJar = androidRuleIdeInfo.resourceJar;
if (resourceJar != null) {
- jars.add(new BlazeJarLibrary(resourceJar, rule.label));
+ jars.add(new BlazeJarLibrary(resourceJar, rule.key));
}
}
}
diff --git a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncListener.java b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncListener.java
index 91d6b57..fda9123 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncListener.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncListener.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.android.sync;
import com.android.tools.idea.res.ResourceFolderRegistry;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.sync.SyncListener;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
@@ -23,7 +24,7 @@
/** Android-specific hooks to run after a blaze sync. */
public class BlazeAndroidSyncListener extends SyncListener.Adapter {
@Override
- public void afterSync(Project project, SyncResult syncResult) {
+ public void afterSync(Project project, BlazeContext context, SyncResult syncResult) {
if (syncResult == SyncResult.SUCCESS || syncResult == SyncResult.PARTIAL_SUCCESS) {
DumbService dumbService = DumbService.getInstance(project);
dumbService.queueTask(new ResourceFolderRegistry.PopulateCachesTask(project));
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 03d8f1b..0755074 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/BlazeAndroidSyncPlugin.java
@@ -26,8 +26,8 @@
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.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
@@ -40,6 +40,7 @@
import com.google.idea.blaze.base.scope.scopes.TimingScope;
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;
@@ -106,6 +107,7 @@
BlazeRoots blazeRoots,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
+ ArtifactLocationDecoder artifactLocationDecoder,
RuleMap ruleMap,
SyncState.Builder syncStateBuilder,
@Nullable SyncState previousSyncState) {
diff --git a/aswb/src/com/google/idea/blaze/android/sync/importer/BlazeAndroidWorkspaceImporter.java b/aswb/src/com/google/idea/blaze/android/sync/importer/BlazeAndroidWorkspaceImporter.java
index 0439e9b..a519f28 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/importer/BlazeAndroidWorkspaceImporter.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/importer/BlazeAndroidWorkspaceImporter.java
@@ -28,8 +28,8 @@
import com.google.idea.blaze.base.ideinfo.AndroidRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.RuleMap;
-import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
@@ -37,9 +37,7 @@
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.scope.output.PerformanceWarning;
import com.google.idea.blaze.base.sync.projectview.ProjectViewRuleImportFilter;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -51,11 +49,8 @@
/** Builds a BlazeWorkspace. */
public final class BlazeAndroidWorkspaceImporter {
- private static final Logger LOG = Logger.getInstance(BlazeAndroidWorkspaceImporter.class);
- private final Project project;
private final BlazeContext context;
- private final WorkspaceRoot workspaceRoot;
private final RuleMap ruleMap;
private final ProjectViewRuleImportFilter importFilter;
@@ -65,9 +60,7 @@
WorkspaceRoot workspaceRoot,
ProjectViewSet projectViewSet,
RuleMap ruleMap) {
- this.project = project;
this.context = context;
- this.workspaceRoot = workspaceRoot;
this.ruleMap = ruleMap;
this.importFilter = new ProjectViewRuleImportFilter(project, workspaceRoot, projectViewSet);
}
@@ -108,7 +101,7 @@
assert androidRuleIdeInfo != null;
if (shouldGenerateResources(androidRuleIdeInfo)
&& shouldGenerateResourceModule(androidRuleIdeInfo)) {
- AndroidResourceModule.Builder builder = new AndroidResourceModule.Builder(rule.label);
+ AndroidResourceModule.Builder builder = new AndroidResourceModule.Builder(rule.key);
workspaceBuilder.androidResourceModules.add(builder);
for (ArtifactLocation artifactLocation : androidRuleIdeInfo.resources) {
@@ -120,7 +113,7 @@
}
TransitiveResourceMap.TransitiveResourceInfo transitiveResourceInfo =
- transitiveResourceMap.get(rule.label);
+ transitiveResourceMap.get(rule.key);
for (ArtifactLocation artifactLocation : transitiveResourceInfo.transitiveResources) {
if (artifactLocation.isSource()) {
builder.addTransitiveResource(artifactLocation);
@@ -128,8 +121,8 @@
workspaceBuilder.generatedResourceLocations.add(artifactLocation);
}
}
- for (Label resourceDependency : transitiveResourceInfo.transitiveResourceRules) {
- if (!resourceDependency.equals(rule.label)) {
+ for (RuleKey resourceDependency : transitiveResourceInfo.transitiveResourceRules) {
+ if (!resourceDependency.equals(rule.key)) {
builder.addTransitiveResourceDependency(resourceDependency);
}
}
@@ -163,7 +156,7 @@
@Nullable
private BlazeResourceLibrary createResourceLibrary(
Collection<AndroidResourceModule> androidResourceModules) {
- Set<File> result = Sets.newHashSet();
+ Set<ArtifactLocation> result = Sets.newHashSet();
for (AndroidResourceModule androidResourceModule : androidResourceModules) {
result.addAll(androidResourceModule.transitiveResources);
}
@@ -195,7 +188,7 @@
Multimap<String, AndroidResourceModule> javaPackageToResourceModule =
ArrayListMultimap.create();
for (AndroidResourceModule androidResourceModule : androidResourceModules) {
- RuleIdeInfo rule = ruleMap.get(androidResourceModule.label);
+ RuleIdeInfo rule = ruleMap.get(androidResourceModule.ruleKey);
AndroidRuleIdeInfo androidRuleIdeInfo = rule.androidRuleIdeInfo;
assert androidRuleIdeInfo != null;
javaPackageToResourceModule.put(
@@ -217,7 +210,7 @@
.append(".R: ");
messageBuilder.append('\n');
for (AndroidResourceModule androidResourceModule : androidResourceModulesWithJavaPackage) {
- messageBuilder.append(" ").append(androidResourceModule.label).append('\n');
+ messageBuilder.append(" ").append(androidResourceModule.ruleKey).append('\n');
}
String message = messageBuilder.toString();
context.output(new PerformanceWarning(message));
@@ -227,7 +220,7 @@
}
}
- Collections.sort(result, (lhs, rhs) -> Label.COMPARATOR.compare(lhs.label, rhs.label));
+ Collections.sort(result, (lhs, rhs) -> RuleKey.COMPARATOR.compare(lhs.ruleKey, rhs.ruleKey));
return ImmutableList.copyOf(result);
}
@@ -243,8 +236,8 @@
lhs.transitiveResources.size(),
rhs.transitiveResources.size()) // Most transitive resources wins
.compare(
- rhs.label.toString().length(),
- lhs.label
+ rhs.ruleKey.toString().length(),
+ lhs.ruleKey
.toString()
.length()) // Shortest label wins - note lhs, rhs are flipped
.result())
diff --git a/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/RuleIdeInfoTransitiveAggregator.java b/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/RuleIdeInfoTransitiveAggregator.java
index 3a7b95c..39a7ab4 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/RuleIdeInfoTransitiveAggregator.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/RuleIdeInfoTransitiveAggregator.java
@@ -16,7 +16,7 @@
package com.google.idea.blaze.android.sync.importer.aggregators;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.RuleMap;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.primitives.Label;
/** Transitive aggregator for RuleIdeInfo. */
diff --git a/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/TransitiveAggregator.java b/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/TransitiveAggregator.java
index 5048910..d2145f3 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/TransitiveAggregator.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/TransitiveAggregator.java
@@ -17,36 +17,36 @@
import com.google.common.collect.Maps;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.RuleMap;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.primitives.Label;
import java.util.Map;
import org.jetbrains.annotations.Nullable;
/** Peforms a transitive reduction on the rule */
public abstract class TransitiveAggregator<T> {
- private Map<Label, T> labelToResult;
+ private Map<RuleKey, T> ruleKeyToResult;
protected TransitiveAggregator(RuleMap ruleMap) {
- this.labelToResult = Maps.newHashMap();
+ this.ruleKeyToResult = Maps.newHashMap();
for (RuleIdeInfo rule : ruleMap.rules()) {
- Label label = rule.label;
- aggregate(label, ruleMap);
+ aggregate(rule.key, ruleMap);
}
}
- protected T getOrDefault(Label key, T defaultValue) {
- T result = labelToResult.get(key);
+ protected T getOrDefault(RuleKey ruleKey, T defaultValue) {
+ T result = ruleKeyToResult.get(ruleKey);
return result != null ? result : defaultValue;
}
@Nullable
- private T aggregate(Label label, RuleMap ruleMap) {
- T result = labelToResult.get(label);
+ private T aggregate(RuleKey ruleKey, RuleMap ruleMap) {
+ T result = ruleKeyToResult.get(ruleKey);
if (result != null) {
return result;
}
- RuleIdeInfo rule = ruleMap.get(label);
+ RuleIdeInfo rule = ruleMap.get(ruleKey);
if (rule == null) {
return null;
}
@@ -54,13 +54,13 @@
result = createForRule(rule);
for (Label depLabel : getDependencies(rule)) {
- T depResult = aggregate(depLabel, ruleMap);
+ T depResult = aggregate(RuleKey.forDependency(rule, depLabel), ruleMap);
if (depResult != null) {
result = reduce(result, depResult);
}
}
- labelToResult.put(label, result);
+ ruleKeyToResult.put(ruleKey, result);
return result;
}
diff --git a/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/TransitiveResourceMap.java b/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/TransitiveResourceMap.java
index f49029d..366e9fd 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/TransitiveResourceMap.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/importer/aggregators/TransitiveResourceMap.java
@@ -20,7 +20,8 @@
import com.google.idea.blaze.base.ideinfo.AndroidRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.RuleMap;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.primitives.Label;
import java.util.List;
import java.util.Set;
@@ -32,7 +33,7 @@
public static class TransitiveResourceInfo {
public static final TransitiveResourceInfo NO_RESOURCES = new TransitiveResourceInfo();
public final Set<ArtifactLocation> transitiveResources = Sets.newHashSet();
- public final Set<Label> transitiveResourceRules = Sets.newHashSet();
+ public final Set<RuleKey> transitiveResourceRules = Sets.newHashSet();
}
public TransitiveResourceMap(RuleMap ruleMap) {
@@ -50,8 +51,8 @@
return super.getDependencies(ruleIdeInfo);
}
- public TransitiveResourceInfo get(Label label) {
- return getOrDefault(label, TransitiveResourceInfo.NO_RESOURCES);
+ public TransitiveResourceInfo get(RuleKey ruleKey) {
+ return getOrDefault(ruleKey, TransitiveResourceInfo.NO_RESOURCES);
}
@Override
@@ -65,7 +66,7 @@
return result;
}
result.transitiveResources.addAll(androidRuleIdeInfo.resources);
- result.transitiveResourceRules.add(ruleIdeInfo.label);
+ result.transitiveResourceRules.add(ruleIdeInfo.key);
return result;
}
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 e4807a9..d8f23d6 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
@@ -20,8 +20,8 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.primitives.Label;
-import java.io.File;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
@@ -35,19 +35,19 @@
*/
@Immutable
public final class AndroidResourceModule implements Serializable {
- private static final long serialVersionUID = 5L;
+ private static final long serialVersionUID = 8L;
- public final Label label;
- public final ImmutableCollection<File> resources;
- public final ImmutableCollection<File> transitiveResources;
- public final ImmutableCollection<Label> transitiveResourceDependencies;
+ public final RuleKey ruleKey;
+ public final ImmutableCollection<ArtifactLocation> resources;
+ public final ImmutableCollection<ArtifactLocation> transitiveResources;
+ public final ImmutableCollection<RuleKey> transitiveResourceDependencies;
public AndroidResourceModule(
- Label label,
- ImmutableCollection<File> resources,
- ImmutableCollection<File> transitiveResources,
- ImmutableCollection<Label> transitiveResourceDependencies) {
- this.label = label;
+ RuleKey ruleKey,
+ ImmutableCollection<ArtifactLocation> resources,
+ ImmutableCollection<ArtifactLocation> transitiveResources,
+ ImmutableCollection<RuleKey> transitiveResourceDependencies) {
+ this.ruleKey = ruleKey;
this.resources = resources;
this.transitiveResources = transitiveResources;
this.transitiveResourceDependencies = transitiveResourceDependencies;
@@ -57,7 +57,7 @@
public boolean equals(Object o) {
if (o instanceof AndroidResourceModule) {
AndroidResourceModule that = (AndroidResourceModule) o;
- return Objects.equal(this.label, that.label)
+ return Objects.equal(this.ruleKey, that.ruleKey)
&& Objects.equal(this.resources, that.resources)
&& Objects.equal(this.transitiveResources, that.transitiveResources)
&& Objects.equal(
@@ -69,15 +69,18 @@
@Override
public int hashCode() {
return Objects.hashCode(
- this.label, this.resources, this.transitiveResources, this.transitiveResourceDependencies);
+ this.ruleKey,
+ this.resources,
+ this.transitiveResources,
+ this.transitiveResourceDependencies);
}
@Override
public String toString() {
return "AndroidResourceModule{"
+ "\n"
- + " label: "
- + label
+ + " rule: "
+ + ruleKey
+ "\n"
+ " resources: "
+ resources
@@ -91,8 +94,8 @@
+ '}';
}
- public static Builder builder(Label label) {
- return new Builder(label);
+ public static Builder builder(RuleKey ruleKey) {
+ return new Builder(ruleKey);
}
public boolean isEmpty() {
@@ -101,13 +104,13 @@
/** Builder for the resource module */
public static class Builder {
- private final Label label;
+ private final RuleKey ruleKey;
private final Set<ArtifactLocation> resources = Sets.newHashSet();
private final Set<ArtifactLocation> transitiveResources = Sets.newHashSet();
- private Set<Label> transitiveResourceDependencies = Sets.newHashSet();
+ private Set<RuleKey> transitiveResourceDependencies = Sets.newHashSet();
- public Builder(Label label) {
- this.label = label;
+ public Builder(RuleKey ruleKey) {
+ this.ruleKey = ruleKey;
}
public Builder addResource(ArtifactLocation resource) {
@@ -131,11 +134,16 @@
return this;
}
- public Builder addTransitiveResourceDependency(Label dependency) {
+ public Builder addTransitiveResourceDependency(RuleKey dependency) {
this.transitiveResourceDependencies.add(dependency);
return this;
}
+ public Builder addTransitiveResourceDependency(Label dependency) {
+ this.transitiveResourceDependencies.add(RuleKey.forPlainTarget(dependency));
+ return this;
+ }
+
public Builder addTransitiveResourceDependency(String dependency) {
return addTransitiveResourceDependency(new Label(dependency));
}
@@ -143,17 +151,15 @@
@NotNull
public AndroidResourceModule build() {
return new AndroidResourceModule(
- label,
+ ruleKey,
ImmutableList.copyOf(
resources
.stream()
- .map(ArtifactLocation::getFile)
.sorted()
.collect(Collectors.toList())),
ImmutableList.copyOf(
transitiveResources
.stream()
- .map(ArtifactLocation::getFile)
.sorted()
.collect(Collectors.toList())),
ImmutableList.copyOf(
diff --git a/aswb/src/com/google/idea/blaze/android/sync/model/BlazeResourceLibrary.java b/aswb/src/com/google/idea/blaze/android/sync/model/BlazeResourceLibrary.java
index 240424e..9489a63 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/model/BlazeResourceLibrary.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/model/BlazeResourceLibrary.java
@@ -17,22 +17,23 @@
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.java.sync.model.BlazeLibrary;
import com.google.idea.blaze.java.sync.model.LibraryKey;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
-import java.io.File;
import javax.annotation.concurrent.Immutable;
/** A library that contains sources. */
@Immutable
public final class BlazeResourceLibrary extends BlazeLibrary {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 2L;
- public final ImmutableList<File> sources;
+ public final ImmutableList<ArtifactLocation> sources;
- public BlazeResourceLibrary(ImmutableList<File> sources) {
+ public BlazeResourceLibrary(ImmutableList<ArtifactLocation> sources) {
super(LibraryKey.forResourceLibrary());
this.sources = sources;
}
@@ -57,9 +58,12 @@
}
@Override
- public void modifyLibraryModel(Project project, Library.ModifiableModel libraryModel) {
- for (File file : sources) {
- libraryModel.addRoot(pathToUrl(file), OrderRootType.SOURCES);
+ public void modifyLibraryModel(
+ Project project,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ Library.ModifiableModel libraryModel) {
+ for (ArtifactLocation file : sources) {
+ libraryModel.addRoot(pathToUrl(artifactLocationDecoder.decode(file)), OrderRootType.SOURCES);
}
}
}
diff --git a/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java
index f6372ed..dbd24d6 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/model/idea/BlazeClassJarProvider.java
@@ -21,6 +21,7 @@
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
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.google.idea.blaze.java.sync.model.BlazeJarLibrary;
import com.google.idea.blaze.java.sync.model.BlazeJavaSyncData;
import com.intellij.openapi.module.Module;
@@ -56,7 +57,8 @@
if (syncData == null) {
return null;
}
- for (File classJar : syncData.importResult.buildOutputJars) {
+ ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
+ for (File classJar : artifactLocationDecoder.decodeAll(syncData.importResult.buildOutputJars)) {
VirtualFile classJarVF = localVfs.findFileByIoFile(classJar);
if (classJarVF == null) {
continue;
@@ -90,6 +92,7 @@
if (syncData == null) {
return null;
}
+ ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
LocalFileSystem localVfs = LocalFileSystem.getInstance();
for (BlazeJarLibrary blazeLibrary : syncData.importResult.libraries.values()) {
LibraryArtifact libraryArtifact = blazeLibrary.libraryArtifact;
@@ -97,7 +100,7 @@
if (classJar == null) {
continue;
}
- VirtualFile libVF = localVfs.findFileByIoFile(classJar.getFile());
+ VirtualFile libVF = localVfs.findFileByIoFile(artifactLocationDecoder.decode(classJar));
if (libVF == null) {
continue;
}
diff --git a/aswb/src/com/google/idea/blaze/android/sync/model/idea/SourceProviderImpl.java b/aswb/src/com/google/idea/blaze/android/sync/model/idea/SourceProviderImpl.java
index 2bf8e82..06a8444 100644
--- a/aswb/src/com/google/idea/blaze/android/sync/model/idea/SourceProviderImpl.java
+++ b/aswb/src/com/google/idea/blaze/android/sync/model/idea/SourceProviderImpl.java
@@ -37,7 +37,7 @@
public SourceProviderImpl(String name, File manifestFile, Collection<File> resDirs) {
this.name = name;
this.manifestFile = manifestFile;
- this.resDirs = resDirs;
+ this.resDirs = ImmutableList.copyOf(resDirs);
}
@Override
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 5fc8793..aff9a7e 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
@@ -16,7 +16,6 @@
package com.google.idea.blaze.android.sync.projectstructure;
import com.android.builder.model.SourceProvider;
-import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -31,6 +30,7 @@
import com.google.idea.blaze.base.ideinfo.AndroidRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
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;
@@ -42,6 +42,7 @@
import com.google.idea.blaze.base.scope.output.PrintOutput;
import com.google.idea.blaze.base.sync.BlazeSyncPlugin;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+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;
@@ -51,6 +52,7 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import java.io.File;
+import java.util.Collection;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@@ -87,21 +89,21 @@
// Create android resource modules
// Because we're setting up dependencies, the modules have to exist before we configure them
- Map<Label, AndroidResourceModule> labelToAndroidResourceModule = Maps.newHashMap();
+ Map<RuleKey, AndroidResourceModule> ruleToAndroidResourceModule = Maps.newHashMap();
for (AndroidResourceModule androidResourceModule :
syncData.importResult.androidResourceModules) {
- labelToAndroidResourceModule.put(androidResourceModule.label, androidResourceModule);
- String moduleName = moduleNameForAndroidModule(androidResourceModule.label);
+ ruleToAndroidResourceModule.put(androidResourceModule.ruleKey, androidResourceModule);
+ String moduleName = moduleNameForAndroidModule(androidResourceModule.ruleKey);
moduleEditor.createModule(moduleName, StdModuleTypes.JAVA);
}
// Configure android resource modules
- for (AndroidResourceModule androidResourceModule : labelToAndroidResourceModule.values()) {
- RuleIdeInfo rule = blazeProjectData.ruleMap.get(androidResourceModule.label);
+ for (AndroidResourceModule androidResourceModule : ruleToAndroidResourceModule.values()) {
+ RuleIdeInfo rule = blazeProjectData.ruleMap.get(androidResourceModule.ruleKey);
AndroidRuleIdeInfo androidRuleIdeInfo = rule.androidRuleIdeInfo;
assert androidRuleIdeInfo != null;
- String moduleName = moduleNameForAndroidModule(rule.label);
+ String moduleName = moduleNameForAndroidModule(rule.key);
Module module = moduleEditor.findModule(moduleName);
assert module != null;
ModifiableRootModel modifiableRootModel = moduleEditor.editModule(module);
@@ -109,14 +111,15 @@
updateAndroidRuleModule(
project,
workspaceRoot,
+ blazeProjectData.artifactLocationDecoder,
androidSdkPlatform,
rule,
module,
modifiableRootModel,
androidResourceModule);
- for (Label resourceDependency : androidResourceModule.transitiveResourceDependencies) {
- if (!labelToAndroidResourceModule.containsKey(resourceDependency)) {
+ for (RuleKey resourceDependency : androidResourceModule.transitiveResourceDependencies) {
+ if (!ruleToAndroidResourceModule.containsKey(resourceDependency)) {
continue;
}
String dependencyModuleName = moduleNameForAndroidModule(resourceDependency);
@@ -157,12 +160,13 @@
int totalRunConfigurationModules = 0;
for (Label label : runConfigurationModuleTargets) {
+ RuleKey ruleKey = RuleKey.forPlainTarget(label);
// If it's a resource module, it will already have been created
- if (labelToAndroidResourceModule.containsKey(label)) {
+ if (ruleToAndroidResourceModule.containsKey(ruleKey)) {
continue;
}
// Ensure the label is a supported android rule that exists
- RuleIdeInfo rule = blazeProjectData.ruleMap.get(label);
+ RuleIdeInfo rule = blazeProjectData.ruleMap.get(ruleKey);
if (rule == null) {
continue;
}
@@ -170,11 +174,18 @@
continue;
}
- String moduleName = moduleNameForAndroidModule(rule.label);
+ String moduleName = moduleNameForAndroidModule(ruleKey);
Module module = moduleEditor.createModule(moduleName, StdModuleTypes.JAVA);
ModifiableRootModel modifiableRootModel = moduleEditor.editModule(module);
updateAndroidRuleModule(
- project, workspaceRoot, androidSdkPlatform, rule, module, modifiableRootModel, null);
+ project,
+ workspaceRoot,
+ blazeProjectData.artifactLocationDecoder,
+ androidSdkPlatform,
+ rule,
+ module,
+ modifiableRootModel,
+ null);
++totalRunConfigurationModules;
}
@@ -196,7 +207,8 @@
/** Ensures a suitable module exists for the given android target. */
@Nullable
public static Module ensureRunConfigurationModule(Project project, Label target) {
- String moduleName = moduleNameForAndroidModule(target);
+ RuleKey ruleKey = RuleKey.forPlainTarget(target);
+ String moduleName = moduleNameForAndroidModule(ruleKey);
Module module = ModuleManager.getInstance(project).findModuleByName(moduleName);
if (module != null) {
return module;
@@ -213,7 +225,7 @@
if (androidSdkPlatform == null) {
return null;
}
- RuleIdeInfo rule = blazeProjectData.ruleMap.get(target);
+ RuleIdeInfo rule = blazeProjectData.ruleMap.get(ruleKey);
if (rule == null) {
return null;
}
@@ -237,6 +249,7 @@
updateAndroidRuleModule(
project,
workspaceRoot,
+ blazeProjectData.artifactLocationDecoder,
androidSdkPlatform,
rule,
newModule,
@@ -247,8 +260,8 @@
return newModule;
}
- public static String moduleNameForAndroidModule(Label label) {
- return label
+ public static String moduleNameForAndroidModule(RuleKey ruleKey) {
+ return ruleKey
.toString()
.substring(2) // Skip initial "//"
.replace('/', '.')
@@ -280,17 +293,20 @@
private static void updateAndroidRuleModule(
Project project,
WorkspaceRoot workspaceRoot,
+ ArtifactLocationDecoder artifactLocationDecoder,
AndroidSdkPlatform androidSdkPlatform,
RuleIdeInfo rule,
Module module,
ModifiableRootModel modifiableRootModel,
@Nullable AndroidResourceModule androidResourceModule) {
- ImmutableCollection<File> resources =
- androidResourceModule != null ? androidResourceModule.resources : ImmutableList.of();
- ImmutableCollection<File> transitiveResources =
+ Collection<File> resources =
androidResourceModule != null
- ? androidResourceModule.transitiveResources
+ ? artifactLocationDecoder.decodeAll(androidResourceModule.resources)
+ : ImmutableList.of();
+ Collection<File> transitiveResources =
+ androidResourceModule != null
+ ? artifactLocationDecoder.decodeAll(androidResourceModule.transitiveResources)
: ImmutableList.of();
AndroidRuleIdeInfo androidRuleIdeInfo = rule.androidRuleIdeInfo;
@@ -300,7 +316,7 @@
ArtifactLocation manifestArtifactLocation = androidRuleIdeInfo.manifest;
File manifest =
manifestArtifactLocation != null
- ? manifestArtifactLocation.getFile()
+ ? artifactLocationDecoder.decode(manifestArtifactLocation)
: new File(moduleDirectory, "AndroidManifest.xml");
String resourceJavaPackage = androidRuleIdeInfo.resourceJavaPackage;
ResourceModuleContentRootCustomizer.setupContentRoots(modifiableRootModel, resources);
@@ -322,7 +338,7 @@
File moduleDirectory,
File manifest,
String resourceJavaPackage,
- ImmutableCollection<File> transitiveResources) {
+ Collection<File> transitiveResources) {
AndroidFacetModuleCustomizer.createAndroidFacet(module);
SourceProvider sourceProvider =
new SourceProviderImpl(module.getName(), manifest, transitiveResources);
diff --git a/aswb/tests/unittests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateTest.java b/aswb/tests/unittests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateTest.java
deleted file mode 100644
index 761643d..0000000
--- a/aswb/tests/unittests/com/google/idea/blaze/android/run/BlazeAndroidRunConfigurationCommonStateTest.java
+++ /dev/null
@@ -1,93 +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.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.idea.blaze.android.cppapi.NdkSupport;
-import com.google.idea.blaze.base.BlazeTestCase;
-import com.google.idea.common.experiments.ExperimentService;
-import com.google.idea.common.experiments.MockExperimentService;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.WriteExternalException;
-import org.jdom.Element;
-import org.jetbrains.annotations.NotNull;
-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 BlazeTestCase {
- private BlazeAndroidRunConfigurationCommonState commonState;
-
- @Override
- protected void initTest(
- @NotNull Container applicationServices, @NotNull Container projectServices) {
- super.initTest(applicationServices, projectServices);
-
- MockExperimentService experimentService = new MockExperimentService();
- applicationServices.register(ExperimentService.class, experimentService);
- // BlazeAndroidRunConfigurationCommonState.isNativeDebuggingEnabled() always
- // returns false if this experiment is false.
- experimentService.setExperiment(NdkSupport.NDK_SUPPORT, true);
-
- commonState = new BlazeAndroidRunConfigurationCommonState(ImmutableList.of());
- }
-
- @Test
- public void readAndWriteShouldMatch() throws InvalidDataException, WriteExternalException {
- commonState.setUserFlags(ImmutableList.of("--flag1", "--flag2"));
- commonState.setNativeDebuggingEnabled(true);
-
- Element element = new Element("test");
- commonState.writeExternal(element);
- BlazeAndroidRunConfigurationCommonState readCommonState =
- new BlazeAndroidRunConfigurationCommonState(ImmutableList.of());
- readCommonState.readExternal(element);
-
- assertThat(readCommonState.getUserFlags()).containsExactly("--flag1", "--flag2").inOrder();
- assertThat(readCommonState.isNativeDebuggingEnabled()).isTrue();
- }
-
- @Test
- public void readAndWriteShouldHandleNulls() throws InvalidDataException, WriteExternalException {
- Element element = new Element("test");
- commonState.writeExternal(element);
- BlazeAndroidRunConfigurationCommonState readCommonState =
- new BlazeAndroidRunConfigurationCommonState(ImmutableList.of());
- readCommonState.readExternal(element);
-
- assertThat(readCommonState.getUserFlags()).isEqualTo(commonState.getUserFlags());
- assertThat(readCommonState.isNativeDebuggingEnabled())
- .isEqualTo(commonState.isNativeDebuggingEnabled());
- }
-
- @Test
- public void readShouldOmitEmptyFlags() throws InvalidDataException, WriteExternalException {
- commonState.setUserFlags(Lists.newArrayList("hi ", "", "I'm", " ", "\t", "Josh\r\n", "\n"));
-
- Element element = new Element("test");
- commonState.writeExternal(element);
- BlazeAndroidRunConfigurationCommonState readCommonState =
- new BlazeAndroidRunConfigurationCommonState(ImmutableList.of());
- readCommonState.readExternal(element);
-
- assertThat(readCommonState.getUserFlags()).containsExactly("hi", "I'm", "Josh").inOrder();
- }
-}
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 dddf2f5..985db7b 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
@@ -30,8 +30,9 @@
import com.google.idea.blaze.base.ideinfo.JavaRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.ideinfo.RuleMapBuilder;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
@@ -62,16 +63,11 @@
@RunWith(JUnit4.class)
public class BlazeAndroidWorkspaceImporterTest extends BlazeTestCase {
- private static final String FAKE_ROOT = "/root";
- private WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File(FAKE_ROOT));
+ private final WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File("/root"));
private static final String FAKE_GEN_ROOT_EXECUTION_PATH_FRAGMENT =
"blaze-out/gcc-4.X.Y-crosstool-v17-hybrid-grtev3-k8-fastbuild/bin";
- private static final String FAKE_GEN_ROOT =
- "/abs_root/_blaze_user/8093958afcfde6c33d08b621dfaa4e09/root/"
- + FAKE_GEN_ROOT_EXECUTION_PATH_FRAGMENT;
-
private static final BlazeImportSettings DUMMY_IMPORT_SETTINGS =
new BlazeImportSettings("", "", "", "", "", BuildSystem.Blaze);
@@ -204,7 +200,8 @@
assertThat(result.androidResourceModules)
.containsExactly(
- AndroidResourceModule.builder(new Label("//java/apps/example:example_debug"))
+ AndroidResourceModule.builder(
+ RuleKey.forPlainTarget(new Label("//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"))
@@ -213,14 +210,16 @@
.addTransitiveResourceDependency("//java/apps/example/lib1:lib1")
.addTransitiveResourceDependency("//java/libraries/shared:shared")
.build(),
- AndroidResourceModule.builder(new Label("//java/apps/example/lib0:lib0"))
+ AndroidResourceModule.builder(
+ RuleKey.forPlainTarget(new Label("//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"))
.addTransitiveResourceDependency("//java/apps/example/lib1:lib1")
.addTransitiveResourceDependency("//java/libraries/shared:shared")
.build(),
- AndroidResourceModule.builder(new Label("//java/apps/example/lib1:lib1"))
+ AndroidResourceModule.builder(
+ RuleKey.forPlainTarget(new Label("//java/apps/example/lib1:lib1")))
.addResourceAndTransitiveResource(source("java/apps/example/lib1/res"))
.addTransitiveResource(source("java/libraries/shared/res"))
.addTransitiveResourceDependency("//java/libraries/shared:shared")
@@ -366,7 +365,8 @@
assertThat(
jars.stream()
- .map(library -> library.libraryArtifact.interfaceJar.getFile().getName())
+ .map(library -> library.libraryArtifact.interfaceJar)
+ .map(artifactLocation -> new File(artifactLocation.relativePath).getName())
.collect(Collectors.toList()))
.containsExactly("lib0_resources.jar");
}
@@ -414,7 +414,8 @@
assertThat(
genJars
.stream()
- .map(library -> library.libraryArtifact.interfaceJar.getFile().getName())
+ .map(library -> library.libraryArtifact.interfaceJar)
+ .map(artifactLocation -> new File(artifactLocation.relativePath).getName())
.collect(Collectors.toList()))
.containsExactly("libidl.jar");
}
@@ -460,7 +461,8 @@
errorCollector.assertNoIssues();
assertThat(result.androidResourceModules)
.containsExactly(
- AndroidResourceModule.builder(new Label("//java/example:resources"))
+ AndroidResourceModule.builder(
+ RuleKey.forPlainTarget(new Label("//java/example:resources")))
.addResourceAndTransitiveResource(source("java/example/res"))
.build());
}
@@ -506,7 +508,12 @@
errorCollector.assertNoIssues();
BlazeResourceLibrary library = result.resourceLibrary;
assertThat(library).isNotNull();
- assertThat(library.sources).containsExactly(new File("/root/java/example2/res"));
+ assertThat(library.sources)
+ .containsExactly(
+ ArtifactLocation.builder()
+ .setRelativePath("java/example2/res")
+ .setIsSource(true)
+ .build());
}
@Test
@@ -551,7 +558,7 @@
assertThat(result.androidResourceModules)
.containsExactly(
- AndroidResourceModule.builder(new Label("//java/example:lib"))
+ AndroidResourceModule.builder(RuleKey.forPlainTarget(new Label("//java/example:lib")))
.addResourceAndTransitiveResource(source("java/example/res"))
.build());
}
@@ -586,16 +593,11 @@
}
private ArtifactLocation source(String relativePath) {
- return ArtifactLocation.builder()
- .setRootPath(FAKE_ROOT)
- .setRelativePath(relativePath)
- .setIsSource(true)
- .build();
+ return ArtifactLocation.builder().setRelativePath(relativePath).setIsSource(true).build();
}
private static ArtifactLocation gen(String relativePath) {
return ArtifactLocation.builder()
- .setRootPath(FAKE_GEN_ROOT)
.setRootExecutionPathFragment(FAKE_GEN_ROOT_EXECUTION_PATH_FRAGMENT)
.setRelativePath(relativePath)
.setIsSource(false)
diff --git a/base/BUILD b/base/BUILD
index add4fdb..0cd244d 100644
--- a/base/BUILD
+++ b/base/BUILD
@@ -42,7 +42,9 @@
"//base",
"//intellij_platform_sdk:plugin_api_for_tests",
"//proto_deps",
+ "//testing:lib",
"@jsr305_annotations//jar",
+ "@junit//jar",
],
)
@@ -69,7 +71,7 @@
)
load(
- "//intellij_test:test_defs.bzl",
+ "//testing:test_defs.bzl",
"intellij_integration_test_suite",
"intellij_unit_test_suite",
)
diff --git a/base/scripts/create_bugreport.sh b/base/scripts/create_bugreport.sh
index 8923bae..d0c40d7 100755
--- a/base/scripts/create_bugreport.sh
+++ b/base/scripts/create_bugreport.sh
@@ -46,7 +46,7 @@
tar_dir=$tmp_dir/$output_name
output_file=${output_name}.tar.gz
-mkdir -p tar_dir
+mkdir -p "$tar_dir"
[ $? -eq 0 ] || { exit 1; }
# Attach process information
diff --git a/base/src/META-INF/blaze-base.xml b/base/src/META-INF/blaze-base.xml
index 606ea98..7559da7 100644
--- a/base/src/META-INF/blaze-base.xml
+++ b/base/src/META-INF/blaze-base.xml
@@ -236,7 +236,7 @@
<extensionPoints>
<extensionPoint qualifiedName="com.google.idea.blaze.SyncListener" interface="com.google.idea.blaze.base.sync.SyncListener"/>
<extensionPoint qualifiedName="com.google.idea.blaze.SyncPlugin" interface="com.google.idea.blaze.base.sync.BlazeSyncPlugin"/>
- <extensionPoint qualifiedName="com.google.idea.blaze.RuleConfigurationFactory" interface="com.google.idea.blaze.base.run.BlazeRuleConfigurationFactory"/>
+ <extensionPoint qualifiedName="com.google.idea.blaze.RunConfigurationFactory" interface="com.google.idea.blaze.base.run.BlazeRunConfigurationFactory"/>
<extensionPoint qualifiedName="com.google.idea.blaze.Prefetcher"
interface="com.google.idea.blaze.base.prefetch.Prefetcher"/>
<extensionPoint qualifiedName="com.google.idea.blaze.PrefetchFileSource"
@@ -265,7 +265,6 @@
<SyncListener implementation="com.google.idea.blaze.base.run.testmap.TestRuleFinderImpl$ClearTestMap"/>
<SyncListener implementation="com.google.idea.blaze.base.rulemaps.SourceToRuleMapImpl$ClearSourceToTargetMap"/>
<SyncListener implementation="com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpecProviderImpl"/>
- <SyncListener implementation="com.google.idea.blaze.base.run.BlazeCommandRunConfigurationUpdater"/>
<SyncPlugin implementation="com.google.idea.blaze.base.lang.buildfile.sync.BuildLangSyncPlugin"/>
<BlazeWizardOptionProvider implementation="com.google.idea.blaze.base.wizard2.BazelWizardOptionProvider"/>
<BuildFlagsProvider implementation="com.google.idea.blaze.base.command.BuildFlagsProviderImpl"/>
@@ -276,6 +275,7 @@
<BlazeCommandRunConfigurationHandlerProvider implementation="com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandlerProvider" order="last"/>
<TestRuleHeuristic implementation="com.google.idea.blaze.base.run.RuleNameHeuristic" order="first"/>
<TestRuleHeuristic implementation="com.google.idea.blaze.base.run.TestSizeHeuristic" order="last" id="TestSizeHeuristic"/>
+ <RunConfigurationFactory implementation="com.google.idea.blaze.base.run.BlazeBuildTargetRunConfigurationFactory" order="last"/>
</extensions>
</idea-plugin>
diff --git a/base/src/com/google/idea/blaze/base/actions/BlazeCompileFileAction.java b/base/src/com/google/idea/blaze/base/actions/BlazeCompileFileAction.java
index 7a94e64..9c9ed3b 100644
--- a/base/src/com/google/idea/blaze/base/actions/BlazeCompileFileAction.java
+++ b/base/src/com/google/idea/blaze/base/actions/BlazeCompileFileAction.java
@@ -83,7 +83,7 @@
VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE);
if (project != null && virtualFile != null) {
return SourceToRuleMap.getInstance(project)
- .getTargetsForSourceFile(new File(virtualFile.getPath()));
+ .getTargetsToBuildForSourceFile(new File(virtualFile.getPath()));
}
return ImmutableList.of();
}
diff --git a/base/src/com/google/idea/blaze/base/buildmap/FileToBuildMap.java b/base/src/com/google/idea/blaze/base/buildmap/FileToBuildMap.java
index 55020f8..b810547 100644
--- a/base/src/com/google/idea/blaze/base/buildmap/FileToBuildMap.java
+++ b/base/src/com/google/idea/blaze/base/buildmap/FileToBuildMap.java
@@ -16,7 +16,6 @@
package com.google.idea.blaze.base.buildmap;
import com.google.common.collect.ImmutableList;
-import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.rulemaps.SourceToRuleMap;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
@@ -46,13 +45,13 @@
return ImmutableList.of();
}
return SourceToRuleMap.getInstance(project)
- .getTargetsForSourceFile(file)
+ .getRulesForSourceFile(file)
.stream()
.map(blazeProjectData.ruleMap::get)
.filter(Objects::nonNull)
.map((ruleIdeInfo) -> ruleIdeInfo.buildFile)
.filter(Objects::nonNull)
- .map(ArtifactLocation::getFile)
+ .map(blazeProjectData.artifactLocationDecoder::decode)
.collect(Collectors.toList());
}
}
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 f4a84d8..d0d9887 100644
--- a/base/src/com/google/idea/blaze/base/command/BlazeFlags.java
+++ b/base/src/com/google/idea/blaze/base/command/BlazeFlags.java
@@ -113,6 +113,7 @@
if (!Strings.isNullOrEmpty(methodName)) {
output.append('#');
output.append(methodName);
+ output.append('$');
}
return output.toString();
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 ac2c392..463f4ae 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/ArtifactLocation.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/ArtifactLocation.java
@@ -16,32 +16,25 @@
package com.google.idea.blaze.base.ideinfo;
import com.google.common.base.Objects;
-import java.io.File;
+import com.google.common.collect.ComparisonChain;
import java.io.Serializable;
import java.nio.file.Paths;
/** Represents a blaze-produced artifact. */
-public final class ArtifactLocation implements Serializable {
- private static final long serialVersionUID = 2L;
+public final class ArtifactLocation implements Serializable, Comparable<ArtifactLocation> {
+ private static final long serialVersionUID = 3L;
- public final String rootPath;
public final String rootExecutionPathFragment;
public final String relativePath;
public final boolean isSource;
private ArtifactLocation(
- String rootPath, String rootExecutionPathFragment, String relativePath, boolean isSource) {
- this.rootPath = rootPath;
+ String rootExecutionPathFragment, String relativePath, boolean isSource) {
this.rootExecutionPathFragment = rootExecutionPathFragment;
this.relativePath = relativePath;
this.isSource = isSource;
}
- /** Returns the root path of the artifact, eg. blaze-out */
- public String getRootPath() {
- return rootPath;
- }
-
/** Gets the path relative to the root path. */
public String getRelativePath() {
return relativePath;
@@ -55,10 +48,6 @@
return !isSource;
}
- public File getFile() {
- return new File(getRootPath(), getRelativePath());
- }
-
/**
* Returns rootExecutionPathFragment + relativePath. For source artifacts, this is simply
* relativePath
@@ -73,16 +62,10 @@
/** Builder for an artifact location */
public static class Builder {
- String rootPath;
String relativePath;
String rootExecutionPathFragment = "";
boolean isSource;
- public Builder setRootPath(String rootPath) {
- this.rootPath = rootPath;
- return this;
- }
-
public Builder setRelativePath(String relativePath) {
this.relativePath = relativePath;
return this;
@@ -99,7 +82,7 @@
}
public ArtifactLocation build() {
- return new ArtifactLocation(rootPath, rootExecutionPathFragment, relativePath, isSource);
+ return new ArtifactLocation(rootExecutionPathFragment, relativePath, isSource);
}
}
@@ -112,19 +95,27 @@
return false;
}
ArtifactLocation that = (ArtifactLocation) o;
- return Objects.equal(rootPath, that.rootPath)
- && Objects.equal(rootExecutionPathFragment, that.rootExecutionPathFragment)
+ return Objects.equal(rootExecutionPathFragment, that.rootExecutionPathFragment)
&& Objects.equal(relativePath, that.relativePath)
&& Objects.equal(isSource, that.isSource);
}
@Override
public int hashCode() {
- return Objects.hashCode(rootPath, rootExecutionPathFragment, relativePath, isSource);
+ return Objects.hashCode(rootExecutionPathFragment, relativePath, isSource);
}
@Override
public String toString() {
- return getFile().toString();
+ return getExecutionRootRelativePath();
+ }
+
+ @Override
+ public int compareTo(ArtifactLocation o) {
+ return ComparisonChain.start()
+ .compare(rootExecutionPathFragment, o.rootExecutionPathFragment)
+ .compare(relativePath, o.relativePath)
+ .compare(isSource, o.isSource)
+ .result();
}
}
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/RuleIdeInfo.java b/base/src/com/google/idea/blaze/base/ideinfo/RuleIdeInfo.java
index a791efc..34bf3ef 100644
--- a/base/src/com/google/idea/blaze/base/ideinfo/RuleIdeInfo.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/RuleIdeInfo.java
@@ -26,8 +26,9 @@
/** Simple implementation of RuleIdeInfo. */
public final class RuleIdeInfo implements Serializable {
- private static final long serialVersionUID = 10L;
+ private static final long serialVersionUID = 12L;
+ public final RuleKey key;
public final Label label;
public final Kind kind;
@Nullable public final ArtifactLocation buildFile;
@@ -58,6 +59,7 @@
@Nullable TestIdeInfo testIdeInfo,
@Nullable ProtoLibraryLegacyInfo protoLibraryLegacyInfo,
@Nullable JavaToolchainIdeInfo javaToolchainIdeInfo) {
+ this.key = RuleKey.forPlainTarget(label);
this.label = label;
this.kind = kind;
this.buildFile = buildFile;
@@ -92,6 +94,10 @@
return false;
}
+ public boolean isPlainTarget() {
+ return true;
+ }
+
public static Builder builder() {
return new Builder();
}
diff --git a/base/src/com/google/idea/blaze/base/ideinfo/RuleKey.java b/base/src/com/google/idea/blaze/base/ideinfo/RuleKey.java
new file mode 100644
index 0000000..8d4cc16
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/ideinfo/RuleKey.java
@@ -0,0 +1,71 @@
+/*
+ * 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.ideinfo;
+
+import com.google.common.base.Objects;
+import com.google.idea.blaze.base.model.primitives.Label;
+import java.io.Serializable;
+import java.util.Comparator;
+
+/** A key that uniquely idenfifies a rule in the rule map */
+public class RuleKey implements Serializable, Comparable<RuleKey> {
+ private static final long serialVersionUID = 1L;
+ public static final Comparator<RuleKey> COMPARATOR =
+ (o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.label.toString(), o2.label.toString());
+
+ public final Label label;
+
+ private RuleKey(Label label) {
+ this.label = label;
+ }
+
+ /** Returns a key identifying dep for a dependency rule -> dep */
+ public static RuleKey forDependency(RuleIdeInfo rule, Label dep) {
+ return new RuleKey(dep);
+ }
+
+ /** Returns a key identifying a plain target */
+ public static RuleKey forPlainTarget(Label label) {
+ return new RuleKey(label);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ RuleKey key = (RuleKey) o;
+ return Objects.equal(label, key.label);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(label);
+ }
+
+ @Override
+ public String toString() {
+ return label.toString();
+ }
+
+ @Override
+ public int compareTo(RuleKey o) {
+ return COMPARATOR.compare(this, o);
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/model/RuleMap.java b/base/src/com/google/idea/blaze/base/ideinfo/RuleMap.java
similarity index 65%
rename from base/src/com/google/idea/blaze/base/model/RuleMap.java
rename to base/src/com/google/idea/blaze/base/ideinfo/RuleMap.java
index 0a46316..365eaf4 100644
--- a/base/src/com/google/idea/blaze/base/model/RuleMap.java
+++ b/base/src/com/google/idea/blaze/base/ideinfo/RuleMap.java
@@ -13,37 +13,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.google.idea.blaze.base.model;
+package com.google.idea.blaze.base.ideinfo;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
-import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.primitives.Label;
import java.io.Serializable;
/** Map of configured targets (and soon aspects). */
public class RuleMap implements Serializable {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 2L;
- private final ImmutableMap<Label, RuleIdeInfo> ruleMap;
+ private final ImmutableMap<RuleKey, RuleIdeInfo> ruleMap;
- public RuleMap(ImmutableMap<Label, RuleIdeInfo> ruleMap) {
+ public RuleMap(ImmutableMap<RuleKey, RuleIdeInfo> ruleMap) {
this.ruleMap = ruleMap;
}
- public RuleIdeInfo get(Label label) {
- return ruleMap.get(label);
+ public RuleIdeInfo get(RuleKey key) {
+ return ruleMap.get(key);
}
- public boolean contains(Label label) {
- return ruleMap.containsKey(label);
+ public boolean contains(RuleKey key) {
+ return ruleMap.containsKey(key);
}
public ImmutableCollection<RuleIdeInfo> rules() {
return ruleMap.values();
}
- public ImmutableMap<Label, RuleIdeInfo> map() {
+ public ImmutableMap<RuleKey, RuleIdeInfo> map() {
return ruleMap;
}
}
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/language/semantics/BuildLanguageSpecProviderImpl.java b/base/src/com/google/idea/blaze/base/lang/buildfile/language/semantics/BuildLanguageSpecProviderImpl.java
index 43ea22a..8c7dcb0 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/language/semantics/BuildLanguageSpecProviderImpl.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/language/semantics/BuildLanguageSpecProviderImpl.java
@@ -19,6 +19,7 @@
import com.google.idea.blaze.base.lang.buildfile.sync.LanguageSpecResult;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.SyncListener;
import com.intellij.openapi.project.Project;
@@ -39,6 +40,7 @@
@Override
public void onSyncComplete(
Project project,
+ BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/language/semantics/RuleDefinition.java b/base/src/com/google/idea/blaze/base/lang/buildfile/language/semantics/RuleDefinition.java
index 089b598..aa85f8d 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/language/semantics/RuleDefinition.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/language/semantics/RuleDefinition.java
@@ -24,16 +24,23 @@
/** Simple implementation of RuleDefinition, from build.proto */
public class RuleDefinition implements Serializable {
- /** This isn't included in the proto -- all other documented attributes seem to be. */
+ /**
+ * In previous versions of blaze/bazel, this wasn't included in the proto. All other documented
+ * attributes seem to be.
+ */
private static final AttributeDefinition NAME_ATTRIBUTE =
new AttributeDefinition("name", Build.Attribute.Discriminator.STRING, true, null, null);
public static RuleDefinition fromProto(Build.RuleDefinition rule) {
+ boolean hasNameAttr = false;
ImmutableMap.Builder<String, AttributeDefinition> map = ImmutableMap.builder();
for (Build.AttributeDefinition attr : rule.getAttributeList()) {
map.put(attr.getName(), AttributeDefinition.fromProto(attr));
+ hasNameAttr |= "name".equals(attr.getName());
}
- map.put(NAME_ATTRIBUTE.name, NAME_ATTRIBUTE);
+ if (!hasNameAttr) {
+ map.put(NAME_ATTRIBUTE.name, NAME_ATTRIBUTE);
+ }
return new RuleDefinition(
rule.getName(), map.build(), rule.hasDocumentation() ? rule.getDocumentation() : null);
}
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 5bd69c7..69b1b77 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
@@ -18,8 +18,8 @@
import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.base.command.info.BlazeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.lang.buildfile.language.semantics.BuildLanguageSpec;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
@@ -29,6 +29,7 @@
import com.google.idea.blaze.base.settings.Blaze;
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;
@@ -55,6 +56,7 @@
BlazeRoots blazeRoots,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
+ ArtifactLocationDecoder artifactLocationDecoder,
RuleMap ruleMap,
SyncState.Builder syncStateBuilder,
@Nullable SyncState previousSyncState) {
diff --git a/base/src/com/google/idea/blaze/base/metrics/Action.java b/base/src/com/google/idea/blaze/base/metrics/Action.java
index 9292cdc..89843df 100644
--- a/base/src/com/google/idea/blaze/base/metrics/Action.java
+++ b/base/src/com/google/idea/blaze/base/metrics/Action.java
@@ -48,7 +48,7 @@
BLAZE_COMMAND_USAGE("ttrpbc"),
OPEN_IN_CODESEARCH("oics"),
- COPY_GOOGLE3_PATH("cg3p"),
+ COPY_DEPOT_PATH("cg3p"),
OPEN_CORRESPONDING_BUILD_FILE("ocbf"),
CREATE_BLAZE_RULE("cbr"),
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 d4e84f7..8a2f278 100644
--- a/base/src/com/google/idea/blaze/base/model/BlazeProjectData.java
+++ b/base/src/com/google/idea/blaze/base/model/BlazeProjectData.java
@@ -16,8 +16,10 @@
package com.google.idea.blaze.base.model;
import com.google.common.collect.ImmutableMultimap;
-import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
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;
@@ -28,16 +30,17 @@
/** The top-level object serialized to cache. */
@Immutable
public class BlazeProjectData implements Serializable {
- private static final long serialVersionUID = 21L;
+ private static final long serialVersionUID = 23L;
public final long syncTime;
public final RuleMap ruleMap;
public final BlazeRoots blazeRoots;
@Nullable public final WorkingSet workingSet;
public final WorkspacePathResolver workspacePathResolver;
+ public final ArtifactLocationDecoder artifactLocationDecoder;
public final WorkspaceLanguageSettings workspaceLanguageSettings;
public final SyncState syncState;
- public final ImmutableMultimap<Label, Label> reverseDependencies;
+ public final ImmutableMultimap<RuleKey, RuleKey> reverseDependencies;
@Nullable public final String vcsName;
public BlazeProjectData(
@@ -46,15 +49,17 @@
BlazeRoots blazeRoots,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
+ ArtifactLocationDecoder artifactLocationDecoder,
WorkspaceLanguageSettings workspaceLangaugeSettings,
SyncState syncState,
- ImmutableMultimap<Label, Label> reverseDependencies,
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies,
String vcsName) {
this.syncTime = syncTime;
this.ruleMap = ruleMap;
this.blazeRoots = blazeRoots;
this.workingSet = workingSet;
this.workspacePathResolver = workspacePathResolver;
+ this.artifactLocationDecoder = artifactLocationDecoder;
this.workspaceLanguageSettings = workspaceLangaugeSettings;
this.syncState = syncState;
this.reverseDependencies = reverseDependencies;
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 96bf0ab..80186c9 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
@@ -45,6 +45,7 @@
GWT_HOST("gwt_host", LanguageClass.JAVA),
GWT_MODULE("gwt_module", LanguageClass.JAVA),
GWT_TEST("gwt_test", LanguageClass.JAVA),
+ TEST_SUITE("test_suite", LanguageClass.GENERIC),
;
static final ImmutableMap<String, Kind> STRING_TO_KIND = makeStringToKindMap();
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 532c347..302a27d 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
@@ -19,7 +19,6 @@
import com.google.idea.blaze.base.ui.BlazeValidationError;
import com.intellij.openapi.diagnostic.Logger;
import java.util.Collection;
-import java.util.Comparator;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@@ -29,9 +28,6 @@
public final class Label extends TargetExpression {
private static final Logger LOG = Logger.getInstance(Label.class);
- public static final Comparator<Label> COMPARATOR =
- (o1, o2) -> String.CASE_INSENSITIVE_ORDER.compare(o1.toString(), o2.toString());
-
public static final long serialVersionUID = 2L;
/** Silently returns null if this is not a valid Label */
diff --git a/base/src/com/google/idea/blaze/base/rulemaps/ReverseDependencyMap.java b/base/src/com/google/idea/blaze/base/rulemaps/ReverseDependencyMap.java
index 0a55a8e..1941eea 100644
--- a/base/src/com/google/idea/blaze/base/rulemaps/ReverseDependencyMap.java
+++ b/base/src/com/google/idea/blaze/base/rulemaps/ReverseDependencyMap.java
@@ -18,18 +18,20 @@
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.RuleMap;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.primitives.Label;
/** Handy class to create an reverse dep map of all rules */
public class ReverseDependencyMap {
- public static ImmutableMultimap<Label, Label> createRdepsMap(RuleMap ruleMap) {
- ImmutableMultimap.Builder<Label, Label> builder = ImmutableMultimap.builder();
+ public static ImmutableMultimap<RuleKey, RuleKey> createRdepsMap(RuleMap ruleMap) {
+ ImmutableMultimap.Builder<RuleKey, RuleKey> builder = ImmutableMultimap.builder();
for (RuleIdeInfo rule : ruleMap.rules()) {
- Label label = rule.label;
+ RuleKey key = rule.key;
for (Label dep : Iterables.concat(rule.dependencies, rule.runtimeDeps)) {
- if (ruleMap.contains(dep)) {
- builder.put(dep, label);
+ RuleKey depKey = RuleKey.forDependency(rule, dep);
+ if (ruleMap.contains(depKey)) {
+ builder.put(depKey, key);
}
}
}
diff --git a/base/src/com/google/idea/blaze/base/rulemaps/SourceToRuleMap.java b/base/src/com/google/idea/blaze/base/rulemaps/SourceToRuleMap.java
index 6fcf01e..df650ea 100644
--- a/base/src/com/google/idea/blaze/base/rulemaps/SourceToRuleMap.java
+++ b/base/src/com/google/idea/blaze/base/rulemaps/SourceToRuleMap.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.base.rulemaps;
import com.google.common.collect.ImmutableCollection;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.primitives.Label;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
@@ -28,5 +29,9 @@
return ServiceManager.getService(project, SourceToRuleMap.class);
}
- ImmutableCollection<Label> getTargetsForSourceFile(File file);
+ /** Returns a set of targets that will cause the file to build */
+ ImmutableCollection<Label> getTargetsToBuildForSourceFile(File file);
+
+ /** Returns the rules that contain a given source file */
+ ImmutableCollection<RuleKey> getRulesForSourceFile(File file);
}
diff --git a/base/src/com/google/idea/blaze/base/rulemaps/SourceToRuleMapImpl.java b/base/src/com/google/idea/blaze/base/rulemaps/SourceToRuleMapImpl.java
index 56fd32f..af86d33 100644
--- a/base/src/com/google/idea/blaze/base/rulemaps/SourceToRuleMapImpl.java
+++ b/base/src/com/google/idea/blaze/base/rulemaps/SourceToRuleMapImpl.java
@@ -20,21 +20,26 @@
import com.google.common.collect.ImmutableMultimap;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.SyncListener;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import java.io.File;
+import java.util.Objects;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
/** Maps source files to their respective targets */
public class SourceToRuleMapImpl implements SourceToRuleMap {
private final Project project;
- private ImmutableMultimap<File, Label> sourceToTargetMap;
+ private ImmutableMultimap<File, RuleKey> sourceToTargetMap;
public static SourceToRuleMapImpl getImpl(Project project) {
return (SourceToRuleMapImpl) ServiceManager.getService(project, SourceToRuleMap.class);
@@ -45,13 +50,35 @@
}
@Override
- public ImmutableCollection<Label> getTargetsForSourceFile(File file) {
- ImmutableMultimap<File, Label> sourceToTargetMap = getSourceToTargetMap();
- return sourceToTargetMap != null ? sourceToTargetMap.get(file) : ImmutableList.of();
+ public ImmutableCollection<Label> getTargetsToBuildForSourceFile(File sourceFile) {
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
+ if (blazeProjectData == null) {
+ return ImmutableList.of();
+ }
+ return ImmutableList.copyOf(
+ getRulesForSourceFile(sourceFile)
+ .stream()
+ .map(blazeProjectData.ruleMap::get)
+ .filter(Objects::nonNull)
+ // TODO(tomlu): For non-plain targets we need to rdep our way back to a target to build
+ // Without this, you won't be able to invoke "build" on (say) a proto_library
+ .filter(RuleIdeInfo::isPlainTarget)
+ .map(rule -> rule.label)
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public ImmutableCollection<RuleKey> getRulesForSourceFile(File sourceFile) {
+ ImmutableMultimap<File, RuleKey> sourceToTargetMap = getSourceToTargetMap();
+ if (sourceToTargetMap == null) {
+ return ImmutableList.of();
+ }
+ return sourceToTargetMap.get(sourceFile);
}
@Nullable
- private synchronized ImmutableMultimap<File, Label> getSourceToTargetMap() {
+ private synchronized ImmutableMultimap<File, RuleKey> getSourceToTargetMap() {
if (this.sourceToTargetMap == null) {
this.sourceToTargetMap = initSourceToTargetMap();
}
@@ -63,17 +90,18 @@
}
@Nullable
- private ImmutableMultimap<File, Label> initSourceToTargetMap() {
+ private ImmutableMultimap<File, RuleKey> initSourceToTargetMap() {
BlazeProjectData blazeProjectData =
BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
if (blazeProjectData == null) {
return null;
}
- ImmutableMultimap.Builder<File, Label> sourceToTargetMap = ImmutableMultimap.builder();
+ ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
+ ImmutableMultimap.Builder<File, RuleKey> sourceToTargetMap = ImmutableMultimap.builder();
for (RuleIdeInfo rule : blazeProjectData.ruleMap.rules()) {
- Label label = rule.label;
+ RuleKey key = rule.key;
for (ArtifactLocation sourceArtifact : rule.sources) {
- sourceToTargetMap.put(sourceArtifact.getFile(), label);
+ sourceToTargetMap.put(artifactLocationDecoder.decode(sourceArtifact), key);
}
}
return sourceToTargetMap.build();
@@ -83,6 +111,7 @@
@Override
public void onSyncComplete(
Project project,
+ BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
diff --git a/base/src/com/google/idea/blaze/base/run/BlazeBeforeRunTaskProvider.java b/base/src/com/google/idea/blaze/base/run/BlazeBeforeRunTaskProvider.java
index aa9d617..7eb51e3 100644
--- a/base/src/com/google/idea/blaze/base/run/BlazeBeforeRunTaskProvider.java
+++ b/base/src/com/google/idea/blaze/base/run/BlazeBeforeRunTaskProvider.java
@@ -15,6 +15,7 @@
*/
package com.google.idea.blaze.base.run;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
import com.google.idea.blaze.base.settings.Blaze;
import com.intellij.execution.BeforeRunTask;
import com.intellij.execution.BeforeRunTaskProvider;
@@ -102,7 +103,8 @@
if (!canExecuteTask(configuration, task)) {
return false;
}
- BlazeCommandRunConfiguration config = (BlazeCommandRunConfiguration) configuration;
- return config.getHandler().executeBeforeRunTask(env);
+ BlazeCommandRunConfigurationRunner runner =
+ env.getCopyableUserData(BlazeCommandRunConfigurationRunner.RUNNER_KEY);
+ return runner.executeBeforeRunTask(env);
}
}
diff --git a/base/src/com/google/idea/blaze/base/run/BlazeBuildTargetRunConfigurationFactory.java b/base/src/com/google/idea/blaze/base/run/BlazeBuildTargetRunConfigurationFactory.java
new file mode 100644
index 0000000..61749cf
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/BlazeBuildTargetRunConfigurationFactory.java
@@ -0,0 +1,45 @@
+/*
+ * 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.run;
+
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.run.producers.BlazeBuildFileRunConfigurationProducer;
+import com.intellij.execution.configurations.ConfigurationFactory;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.openapi.project.Project;
+
+/**
+ * A factory creating run configurations based on BUILD file targets. Runs last, as a fallback for
+ * the case where no more specialized factory handles the target.
+ */
+public class BlazeBuildTargetRunConfigurationFactory extends BlazeRunConfigurationFactory {
+
+ @Override
+ public boolean handlesTarget(Project project, BlazeProjectData blazeProjectData, Label target) {
+ return BlazeBuildFileRunConfigurationProducer.handlesTarget(project, target);
+ }
+
+ @Override
+ protected ConfigurationFactory getConfigurationFactory() {
+ return BlazeCommandRunConfigurationType.getInstance().getFactory();
+ }
+
+ @Override
+ public void setupConfiguration(RunConfiguration configuration, Label target) {
+ BlazeBuildFileRunConfigurationProducer.setupConfiguration(configuration, target);
+ }
+}
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 4d53ff5..5405d02 100644
--- a/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfiguration.java
+++ b/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfiguration.java
@@ -21,16 +21,16 @@
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerEditor;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerProvider;
-import com.google.idea.blaze.base.run.confighandler.BlazeUnknownRunConfigurationHandler;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
+import com.google.idea.blaze.base.run.state.RunConfigurationState;
+import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.base.ui.UiUtil;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
-import com.intellij.execution.RunManager;
import com.intellij.execution.RunnerIconProvider;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.LocatableConfigurationBase;
@@ -47,12 +47,14 @@
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBTextField;
import com.intellij.util.ui.UIUtil;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.JComponent;
+import org.jdom.Attribute;
import org.jdom.Element;
-import org.jetbrains.annotations.NotNull;
/** A run configuration which executes Blaze commands. */
public class BlazeCommandRunConfiguration extends LocatableConfigurationBase
@@ -63,35 +65,41 @@
private static final String TARGET_TAG = "blaze-target";
private static final String KIND_ATTR = "kind";
- // Null for configurations created since restart.
- @Nullable private Element externalElementBackup;
- // Null when there is no target.
+ /** The last serialized state of the configuration. */
+ private Element elementState = new Element("dummy");
+
@Nullable private TargetExpression target;
// Null if the target is null, not a Label, or not a known rule.
@Nullable private Kind targetKind;
+ private BlazeCommandRunConfigurationHandlerProvider handlerProvider;
private BlazeCommandRunConfigurationHandler handler;
- // Null if the handler is BlazeUnknownRunConfigurationHandler.
- @Nullable private BlazeCommandRunConfigurationHandlerProvider handlerProvider;
public BlazeCommandRunConfiguration(Project project, ConfigurationFactory factory, String name) {
super(project, factory, name);
- handler = new BlazeUnknownRunConfigurationHandler(this);
+ // start with whatever fallback is present
+ handlerProvider = BlazeCommandRunConfigurationHandlerProvider.findHandlerProvider(null);
+ handler = handlerProvider.createHandler(this);
+ try {
+ handler.getState().readExternal(elementState);
+ } catch (InvalidDataException e) {
+ LOG.error(e);
+ }
}
/** @return The configuration's {@link BlazeCommandRunConfigurationHandler}. */
- @NotNull
public BlazeCommandRunConfigurationHandler getHandler() {
return handler;
}
/**
- * Gets the configuration's {@link BlazeCommandRunConfigurationHandler} if it is an instance of
- * the given class; otherwise returns null.
+ * Gets the configuration's handler's {@link RunConfigurationState} if it is an instance of the
+ * given class; otherwise returns null.
*/
@Nullable
- public <T extends BlazeCommandRunConfigurationHandler> T getHandlerIfType(Class<T> type) {
- if (type.isInstance(handler)) {
- return type.cast(handler);
+ public <T extends RunConfigurationState> T getHandlerStateIfType(Class<T> type) {
+ RunConfigurationState handlerState = handler.getState();
+ if (type.isInstance(handlerState)) {
+ return type.cast(handlerState);
} else {
return null;
}
@@ -105,32 +113,42 @@
public void setTarget(@Nullable TargetExpression target) {
this.target = target;
- RuleIdeInfo rule = getRuleForTarget();
- targetKind = rule != null ? rule.kind : null;
+ targetKind = getKindForTarget();
BlazeCommandRunConfigurationHandlerProvider handlerProvider =
BlazeCommandRunConfigurationHandlerProvider.findHandlerProvider(targetKind);
- setHandlerIfDifferentProvider(handlerProvider);
+ updateHandlerIfDifferentProvider(handlerProvider);
}
- private void setHandlerIfDifferentProvider(
+ private void updateHandlerIfDifferentProvider(
BlazeCommandRunConfigurationHandlerProvider newProvider) {
- // Only change the handler if the provider has changed.
- if (handlerProvider != newProvider) {
- handlerProvider = newProvider;
- handler = newProvider.createHandler(this);
+ if (handlerProvider == newProvider) {
+ return;
+ }
+ try {
+ handler.getState().writeExternal(elementState);
+ } catch (WriteExternalException e) {
+ LOG.error(e);
+ }
+ handlerProvider = newProvider;
+ handler = newProvider.createHandler(this);
+ try {
+ handler.getState().readExternal(elementState);
+ } catch (InvalidDataException e) {
+ LOG.error(e);
}
}
/**
- * Returns the single blaze target corresponding to the configuration's target expression, if one
- * exists. Returns null if the target expression points to multiple blaze targets, or wasn't
- * included in the latest sync.
+ * Returns the {@link Kind} of the single blaze target corresponding to the configuration's target
+ * expression, if it can be determined. Returns null if the target expression points to multiple
+ * blaze targets.
*/
@Nullable
- public RuleIdeInfo getRuleForTarget() {
+ public Kind getKindForTarget() {
if (target instanceof Label) {
- return RuleFinder.getInstance().ruleForTarget(getProject(), (Label) target);
+ RuleIdeInfo rule = RuleFinder.getInstance().ruleForTarget(getProject(), (Label) target);
+ return rule != null ? rule.kind : null;
}
return null;
}
@@ -141,9 +159,9 @@
* known rule, and "unknown target" if there is no target.
*/
public String getTargetKindName() {
- RuleIdeInfo rule = getRuleForTarget();
- if (rule != null) {
- return rule.kind.toString();
+ Kind kind = getKindForTarget();
+ if (kind != null) {
+ return kind.toString();
} else if (target instanceof Label) {
return "unknown rule";
} else if (target != null) {
@@ -153,36 +171,12 @@
}
}
- // TODO This method can be private after BlazeCommandRunConfigurationUpdater is removed.
- void loadExternalElementBackup() {
- if (externalElementBackup != null) {
- try {
- handler.readExternal(externalElementBackup);
- } catch (InvalidDataException e) {
- // This is what IntelliJ does when getting this exception while loading a configuration.
- LOG.error(e);
- }
- }
- }
-
@Override
public void checkConfiguration() throws RuntimeConfigurationException {
- // Our handler check and its quick fix are not valid when we don't have BlazeProjectData.
+ // Our handler check is not valid when we don't have BlazeProjectData.
if (BlazeProjectDataManager.getInstance(getProject()).getBlazeProjectData() == null) {
throw new RuntimeConfigurationError(
- "Configuration cannot be used or modified while project is syncing.");
- }
- if (isConfigurationInvalidated()) {
- throw new RuntimeConfigurationError(
- "A property of the target unexpectedly changed. The configuration must be updated. "
- + "Some configuration settings may be lost.",
- () -> {
- BlazeCommandRunConfigurationHandler oldHandler = handler;
- setTarget(target);
- if (handler != oldHandler) {
- loadExternalElementBackup();
- }
- });
+ "Configuration cannot be run until project has been synced.");
}
if (target == null) {
throw new RuntimeConfigurationError(
@@ -196,25 +190,11 @@
handler.checkConfiguration();
}
- private boolean isConfigurationInvalidated() {
- boolean configurationInvalidated = handler instanceof BlazeUnknownRunConfigurationHandler;
- if (!configurationInvalidated) {
- RuleIdeInfo rule = getRuleForTarget();
- Kind expectedKind = rule != null ? rule.kind : null;
- configurationInvalidated = targetKind != expectedKind;
- }
- if (!configurationInvalidated) {
- configurationInvalidated =
- handlerProvider
- != BlazeCommandRunConfigurationHandlerProvider.findHandlerProvider(targetKind);
- }
- return configurationInvalidated;
- }
-
@Override
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
- externalElementBackup = element.clone();
+ element = element.clone();
+
// Target is persisted as a tag to permit multiple targets in the future.
Element targetElement = element.getChild(TARGET_TAG);
if (targetElement != null && !Strings.isNullOrEmpty(targetElement.getTextTrim())) {
@@ -225,16 +205,8 @@
// BlazeAndroid(Binary/Test)RunConfiguration elements can be read.
// TODO remove in 2.1 once BlazeAndroidBinaryRunConfigurationType and
// BlazeAndroidTestRunConfigurationType have been removed.
- String targetString =
- element.getAttributeValue(
- TARGET_TAG); // The attribute ID happens to be identical to the tag ID.
- if (targetString != null) {
- target = TargetExpression.fromString(targetString);
- // Once the above is removed, 'target = null;' should be
- // the only thing in the outer else clause.
- } else {
- target = null;
- }
+ String targetString = element.getAttributeValue(TARGET_TAG);
+ target = targetString != null ? TargetExpression.fromString(targetString) : null;
}
// Because BlazeProjectData is not available when configurations are loading,
// we can't call setTarget and have it find the appropriate handler provider.
@@ -243,21 +215,24 @@
BlazeCommandRunConfigurationHandlerProvider handlerProvider =
BlazeCommandRunConfigurationHandlerProvider.getHandlerProvider(providerId);
if (handlerProvider != null) {
- setHandlerIfDifferentProvider(handlerProvider);
+ updateHandlerIfDifferentProvider(handlerProvider);
}
- handler.readExternal(element);
+
+ element.removeAttribute(KIND_ATTR);
+ element.removeAttribute(HANDLER_ATTR);
+ element.removeChildren(TARGET_TAG);
+ // remove legacy attribute, if present
+ element.removeAttribute(TARGET_TAG);
+
+ this.elementState = element;
+ handler.getState().readExternal(elementState);
}
@Override
@SuppressWarnings("ThrowsUncheckedException")
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
- // We can't write externalElementBackup contents; doing so would cause the configuration
- // xml to retain duplicate elements and grow across reopenings.
- // We also can't use the approach in BlazeUnknownRunConfigurationHandler;
- // this can revive intentionally deleted attributes/elements such as user flags.
if (target != null) {
- // Target is persisted as a tag to permit multiple targets in the future.
Element targetElement = new Element(TARGET_TAG);
targetElement.setText(target.toString());
if (targetKind != null) {
@@ -265,95 +240,92 @@
}
element.addContent(targetElement);
}
- if (handlerProvider != null) {
- element.setAttribute(HANDLER_ATTR, handlerProvider.getId());
+ element.setAttribute(HANDLER_ATTR, handlerProvider.getId());
+ handler.getState().writeExternal(elementState);
+
+ // copy our internal state to the provided Element, skipping items already present
+ Set<String> baseAttributes =
+ element.getAttributes().stream().map(Attribute::getName).collect(Collectors.toSet());
+ for (Attribute attribute : elementState.getAttributes()) {
+ if (!baseAttributes.contains(attribute.getName())) {
+ element.setAttribute(attribute.clone());
+ }
}
- handler.writeExternal(element);
+ Set<String> baseChildren =
+ element.getChildren().stream().map(Element::getName).collect(Collectors.toSet());
+ for (Element child : elementState.getChildren()) {
+ if (!baseChildren.contains(child.getName())) {
+ element.addContent(child.clone());
+ }
+ }
}
@Override
public BlazeCommandRunConfiguration clone() {
final BlazeCommandRunConfiguration configuration = (BlazeCommandRunConfiguration) super.clone();
- if (externalElementBackup != null) {
- configuration.externalElementBackup = externalElementBackup.clone();
- }
+ configuration.elementState = elementState.clone();
configuration.target = target;
configuration.targetKind = targetKind;
- configuration.handler = handler.cloneFor(configuration);
configuration.handlerProvider = handlerProvider;
+ configuration.handler = handlerProvider.createHandler(this);
+ try {
+ configuration.handler.getState().readExternal(configuration.elementState);
+ } catch (InvalidDataException e) {
+ LOG.error(e);
+ }
+
return configuration;
}
@Override
@Nullable
- public RunProfileState getState(
- @NotNull Executor executor, @NotNull ExecutionEnvironment environment)
+ public RunProfileState getState(Executor executor, ExecutionEnvironment environment)
throws ExecutionException {
- return handler.getState(executor, environment);
+ BlazeCommandRunConfigurationRunner runner = handler.createRunner(executor, environment);
+ if (runner != null) {
+ environment.putCopyableUserData(BlazeCommandRunConfigurationRunner.RUNNER_KEY, runner);
+ return runner.getRunProfileState(executor, environment);
+ }
+ return null;
}
@Override
@Nullable
public String suggestedName() {
- return handler.suggestedName();
- }
-
- @Override
- public boolean isGeneratedName() {
- return handler.isGeneratedName(super.isGeneratedName());
+ return handler.suggestedName(this);
}
@Override
@Nullable
- public Icon getExecutorIcon(@NotNull RunConfiguration configuration, @NotNull Executor executor) {
+ public Icon getExecutorIcon(RunConfiguration configuration, Executor executor) {
return handler.getExecutorIcon(configuration, executor);
}
@Override
- @NotNull
public SettingsEditor<? extends BlazeCommandRunConfiguration> getConfigurationEditor() {
return new BlazeCommandRunConfigurationSettingsEditor(this);
}
static class BlazeCommandRunConfigurationSettingsEditor
extends SettingsEditor<BlazeCommandRunConfiguration> {
- @Nullable private BlazeCommandRunConfigurationHandlerProvider handlerProvider;
- private BlazeCommandRunConfigurationHandlerEditor handlerEditor;
- @Nullable private JComponent handlerComponent;
+
+ private BlazeCommandRunConfigurationHandlerProvider handlerProvider;
+ private BlazeCommandRunConfigurationHandler handler;
+ private RunConfigurationStateEditor handlerStateEditor;
+ private JComponent handlerStateComponent;
+ private Element elementState;
private final Box editor;
private final JBLabel targetExpressionLabel;
private final JBTextField targetField = new JBTextField(1);
- private boolean isEditable;
-
- public BlazeCommandRunConfigurationSettingsEditor(BlazeCommandRunConfiguration config) {
+ BlazeCommandRunConfigurationSettingsEditor(BlazeCommandRunConfiguration config) {
+ elementState = config.elementState.clone();
targetExpressionLabel = new JBLabel(UIUtil.ComponentStyle.LARGE);
editor = UiUtil.createBox(targetExpressionLabel, targetField);
targetField.getEmptyText().setText("Full target expression starting with //");
updateTargetExpressionLabel(config);
updateHandlerEditor(config);
- setEditable(isConfigurationEditable(config));
- }
-
- private static boolean isConfigurationEditable(BlazeCommandRunConfiguration config) {
- RunConfiguration template =
- RunManager.getInstance(config.getProject())
- .getConfigurationTemplate(config.getFactory())
- .getConfiguration();
- if (config == template) {
- return true; // The default template is always editable.
- }
- return BlazeProjectDataManager.getInstance(config.getProject()).getBlazeProjectData() != null
- && !config.isConfigurationInvalidated();
- }
-
- private void setEditable(boolean editable) {
- isEditable = editable;
- targetField.setEnabled(isEditable);
- if (handlerComponent != null) {
- handlerComponent.setVisible(isEditable);
- }
}
private void updateTargetExpressionLabel(BlazeCommandRunConfiguration config) {
@@ -365,56 +337,66 @@
private void updateHandlerEditor(BlazeCommandRunConfiguration config) {
handlerProvider = config.handlerProvider;
- handlerEditor = config.handler.getHandlerEditor();
+ handler = handlerProvider.createHandler(config);
+ try {
+ handler.getState().readExternal(config.elementState);
+ } catch (InvalidDataException e) {
+ LOG.error(e);
+ }
+ handlerStateEditor = handler.getState().getEditor(config.getProject());
- if (handlerComponent != null) {
- editor.remove(handlerComponent);
+ if (handlerStateComponent != null) {
+ editor.remove(handlerStateComponent);
}
- handlerComponent = handlerEditor.createEditor();
- if (handlerComponent != null) {
- editor.add(handlerComponent);
- }
+ handlerStateComponent = handlerStateEditor.createComponent();
+ editor.add(handlerStateComponent);
}
@Override
- @NotNull
protected JComponent createEditor() {
return editor;
}
@Override
protected void resetEditorFrom(BlazeCommandRunConfiguration config) {
+ elementState = config.elementState.clone();
updateTargetExpressionLabel(config);
if (config.handlerProvider != handlerProvider) {
updateHandlerEditor(config);
}
- setEditable(isConfigurationEditable(config));
targetField.setText(config.target == null ? null : config.target.toString());
- handlerEditor.resetEditorFrom(config.handler);
+ handlerStateEditor.resetEditorFrom(config.handler.getState());
}
@Override
protected void applyEditorTo(BlazeCommandRunConfiguration config) {
- if (!isEditable) {
- return;
+ // update the editor's elementState
+ handlerStateEditor.applyEditorTo(handler.getState());
+ try {
+ handler.getState().writeExternal(elementState);
+ } catch (WriteExternalException e) {
+ LOG.error(e);
}
- applyTarget(config);
+
+ // now set the config's state, based on the editor's (possibly out of date) handler
+ config.updateHandlerIfDifferentProvider(handlerProvider);
+ config.elementState = elementState.clone();
+ try {
+ config.handler.getState().readExternal(config.elementState);
+ } catch (InvalidDataException e) {
+ LOG.error(e);
+ }
+
+ // finally, update the handler
+ String targetString = targetField.getText();
+ config.setTarget(
+ Strings.isNullOrEmpty(targetString) ? null : TargetExpression.fromString(targetString));
updateTargetExpressionLabel(config);
if (config.handlerProvider != handlerProvider) {
updateHandlerEditor(config);
- handlerEditor.resetEditorFrom(config.handler);
+ handlerStateEditor.resetEditorFrom(config.handler.getState());
} else {
- handlerEditor.applyEditorTo(config.handler);
- }
- }
-
- private void applyTarget(BlazeCommandRunConfiguration config) {
- String targetString = targetField.getText();
- BlazeCommandRunConfigurationHandler oldHandler = config.handler;
- config.setTarget(
- Strings.isNullOrEmpty(targetString) ? null : TargetExpression.fromString(targetString));
- if (config.handler != oldHandler) {
- config.loadExternalElementBackup();
+ handlerStateEditor.applyEditorTo(config.handler.getState());
}
}
}
diff --git a/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationUpdater.java b/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationUpdater.java
deleted file mode 100644
index c04c988..0000000
--- a/base/src/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationUpdater.java
+++ /dev/null
@@ -1,59 +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.run;
-
-import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.primitives.Label;
-import com.google.idea.blaze.base.projectview.ProjectViewSet;
-import com.google.idea.blaze.base.run.confighandler.BlazeUnknownRunConfigurationHandler;
-import com.google.idea.blaze.base.settings.BlazeImportSettings;
-import com.google.idea.blaze.base.sync.SyncListener;
-import com.intellij.execution.RunManager;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.openapi.project.Project;
-
-/**
- * Added in 1.9 to facilitate updating existing configurations to include the new handler-id and
- * kind attributes. To be removed in 2.1.
- */
-public class BlazeCommandRunConfigurationUpdater extends SyncListener.Adapter {
- @Override
- public void onSyncComplete(
- Project project,
- BlazeImportSettings importSettings,
- ProjectViewSet projectViewSet,
- BlazeProjectData blazeProjectData,
- SyncResult syncResult) {
- final RunManager runManager = RunManager.getInstance(project);
- for (RunConfiguration configuration : runManager.getAllConfigurationsList()) {
- if (configuration instanceof BlazeCommandRunConfiguration) {
- BlazeCommandRunConfiguration blazeConfig = (BlazeCommandRunConfiguration) configuration;
- // Only update configurations with unknown handlers, as this will
- // reset any changes made to the handler data since the project loaded.
- if (blazeConfig.getHandler() instanceof BlazeUnknownRunConfigurationHandler
- // Also skip unresolved Label targets; these cannot safely be defaulted
- // to the generic handler and should continue to display an error instead.
- // If the Blaze cache is invalidated, all Labels can be unresolved;
- // blindly updating them would result in loss of handler settings.
- && !(blazeConfig.getTarget() instanceof Label
- && blazeConfig.getRuleForTarget() == null)) {
- blazeConfig.setTarget(blazeConfig.getTarget());
- blazeConfig.loadExternalElementBackup();
- }
- }
- }
- }
-}
diff --git a/base/src/com/google/idea/blaze/base/run/BlazeRuleConfigurationFactory.java b/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationFactory.java
similarity index 70%
rename from base/src/com/google/idea/blaze/base/run/BlazeRuleConfigurationFactory.java
rename to base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationFactory.java
index f430596..1010640 100644
--- a/base/src/com/google/idea/blaze/base/run/BlazeRuleConfigurationFactory.java
+++ b/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationFactory.java
@@ -15,8 +15,8 @@
*/
package com.google.idea.blaze.base.run;
-import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.model.primitives.Label;
import com.intellij.execution.RunManager;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.ConfigurationFactory;
@@ -24,14 +24,14 @@
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
-/** A factory creating run configurations based on Blaze rules. */
-public abstract class BlazeRuleConfigurationFactory {
- public static final ExtensionPointName<BlazeRuleConfigurationFactory> EP_NAME =
- ExtensionPointName.create("com.google.idea.blaze.RuleConfigurationFactory");
+/** A factory creating run configurations based on Blaze targets. */
+public abstract class BlazeRunConfigurationFactory {
+ public static final ExtensionPointName<BlazeRunConfigurationFactory> EP_NAME =
+ ExtensionPointName.create("com.google.idea.blaze.RunConfigurationFactory");
- /** Returns whether this factory can handle a rule. */
- public abstract boolean handlesRule(
- WorkspaceLanguageSettings workspaceLanguageSettings, RuleIdeInfo rule);
+ /** Returns whether this factory can handle a target. */
+ public abstract boolean handlesTarget(
+ Project project, BlazeProjectData blazeProjectData, Label target);
/**
* Returns whether this factory can initialize a configuration. <br>
@@ -44,17 +44,17 @@
}
/** Constructs and initializes {@link RunnerAndConfigurationSettings} for the given rule. */
- public RunnerAndConfigurationSettings createForRule(
- Project project, RunManager runManager, RuleIdeInfo rule) {
+ public RunnerAndConfigurationSettings createForTarget(
+ Project project, RunManager runManager, Label target) {
ConfigurationFactory factory = getConfigurationFactory();
RunConfiguration configuration = factory.createTemplateConfiguration(project, runManager);
- setupConfiguration(configuration, rule);
+ setupConfiguration(configuration, target);
return runManager.createConfiguration(configuration, factory);
}
/** The factory used to create configurations. */
protected abstract ConfigurationFactory getConfigurationFactory();
- /** Initialize the configuration for the given rule. */
- public abstract void setupConfiguration(RunConfiguration configuration, RuleIdeInfo rule);
+ /** Initialize the configuration for the given target. */
+ public abstract void setupConfiguration(RunConfiguration configuration, Label target);
}
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 ea4aae6..80ae557 100755
--- a/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationSyncListener.java
+++ b/base/src/com/google/idea/blaze/base/run/BlazeRunConfigurationSyncListener.java
@@ -16,15 +16,14 @@
package com.google.idea.blaze.base.run;
import com.google.common.collect.Sets;
-import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
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.TargetExpression;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.projectview.section.sections.TargetSection;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.SyncListener;
-import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.intellij.execution.RunManager;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.RunConfiguration;
@@ -39,6 +38,7 @@
@Override
public void onSyncComplete(
Project project,
+ BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
@@ -50,13 +50,14 @@
Set<Label> labelsWithConfigs = labelsWithConfigs(project);
Set<TargetExpression> targetExpressions =
Sets.newHashSet(projectViewSet.listItems(TargetSection.KEY));
- for (RuleIdeInfo rule : blazeProjectData.ruleMap.rules()) {
- maybeAddRunConfiguration(
- project,
- blazeProjectData.workspaceLanguageSettings,
- targetExpressions,
- labelsWithConfigs,
- rule);
+ // We only auto-generate configurations for rules listed in the project view.
+ for (TargetExpression target : targetExpressions) {
+ if (!(target instanceof Label) || labelsWithConfigs.contains(target)) {
+ continue;
+ }
+ Label label = (Label) target;
+ labelsWithConfigs.add(label);
+ maybeAddRunConfiguration(project, blazeProjectData, label);
}
});
}
@@ -83,24 +84,14 @@
* for that target.
*/
private static void maybeAddRunConfiguration(
- Project project,
- WorkspaceLanguageSettings workspaceLanguageSettings,
- Set<TargetExpression> importTargets,
- Set<Label> labelsWithConfigs,
- RuleIdeInfo rule) {
- Label label = rule.label;
- // We only auto-generate configurations for rules listed in the project view.
- if (!importTargets.contains(label) || labelsWithConfigs.contains(label)) {
- return;
- }
- labelsWithConfigs.add(label);
+ Project project, BlazeProjectData blazeProjectData, Label label) {
final RunManager runManager = RunManager.getInstance(project);
- for (BlazeRuleConfigurationFactory configurationFactory :
- BlazeRuleConfigurationFactory.EP_NAME.getExtensions()) {
- if (configurationFactory.handlesRule(workspaceLanguageSettings, rule)) {
+ for (BlazeRunConfigurationFactory configurationFactory :
+ BlazeRunConfigurationFactory.EP_NAME.getExtensions()) {
+ if (configurationFactory.handlesTarget(project, blazeProjectData, label)) {
final RunnerAndConfigurationSettings settings =
- configurationFactory.createForRule(project, runManager, rule);
+ configurationFactory.createForTarget(project, runManager, label);
runManager.addConfiguration(settings, false /* isShared */);
if (runManager.getSelectedConfiguration() == null) {
// TODO(joshgiles): Better strategy for picking initially selected config.
diff --git a/base/src/com/google/idea/blaze/base/run/RuleNameHeuristic.java b/base/src/com/google/idea/blaze/base/run/RuleNameHeuristic.java
index 8f92d75..f766ceb 100644
--- a/base/src/com/google/idea/blaze/base/run/RuleNameHeuristic.java
+++ b/base/src/com/google/idea/blaze/base/run/RuleNameHeuristic.java
@@ -26,7 +26,16 @@
@Override
public boolean matchesSource(RuleIdeInfo rule, File sourceFile, @Nullable TestSize testSize) {
- String sourceName = FileUtil.getNameWithoutExtension(sourceFile);
- return sourceName.equals(rule.label.ruleName().toString());
+ String filePathWithoutExtension = FileUtil.getNameWithoutExtension(sourceFile.getPath());
+ String ruleName = rule.label.ruleName().toString();
+ if (!filePathWithoutExtension.endsWith(ruleName)) {
+ return false;
+ }
+ int i = filePathWithoutExtension.length() - ruleName.length() - 1;
+ if (i < 0) {
+ // Equal length
+ return true;
+ }
+ return filePathWithoutExtension.charAt(i) == '/';
}
}
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 97a9aaa..0080b3f 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
@@ -15,226 +15,52 @@
*/
package com.google.idea.blaze.base.run.confighandler;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-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.issueparser.IssueOutputLineProcessor;
-import com.google.idea.blaze.base.metrics.Action;
-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.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
-import com.google.idea.blaze.base.run.processhandler.LineProcessingProcessAdapter;
-import com.google.idea.blaze.base.run.processhandler.ScopedBlazeProcessHandler;
-import com.google.idea.blaze.base.scope.BlazeContext;
-import com.google.idea.blaze.base.scope.scopes.IdeaLogScope;
-import com.google.idea.blaze.base.scope.scopes.IssuesScope;
-import com.google.idea.blaze.base.scope.scopes.LoggedTimingScope;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
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.ui.UiUtil;
-import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
-import com.intellij.execution.configurations.CommandLineState;
import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.configurations.RunProfile;
-import com.intellij.execution.configurations.RunProfileState;
-import com.intellij.execution.configurations.RuntimeConfigurationError;
import com.intellij.execution.configurations.RuntimeConfigurationException;
-import com.intellij.execution.process.ProcessHandler;
-import com.intellij.execution.process.ProcessListener;
import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.ComboBox;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.ui.components.JBTextField;
-import com.intellij.util.execution.ParametersListUtil;
-import java.io.File;
-import java.util.List;
import javax.annotation.Nullable;
-import javax.swing.DefaultComboBoxModel;
import javax.swing.Icon;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-import javax.swing.ScrollPaneConstants;
-import org.jdom.Element;
-import org.jetbrains.annotations.NotNull;
/**
* Generic handler for {@link BlazeCommandRunConfiguration}s, used as a fallback in the case where
* no other handlers are more relevant.
*/
-public class BlazeCommandGenericRunConfigurationHandler
+public final class BlazeCommandGenericRunConfigurationHandler
implements BlazeCommandRunConfigurationHandler {
- private static final String COMMAND_ATTR = "blaze-command";
- private static final String USER_BLAZE_FLAG_TAG = "blaze-user-flag";
- private static final String USER_EXE_FLAG_TAG = "blaze-user-exe-flag";
- private static final String BLAZE_BINARY_TAG = "blaze-binary";
- /** The configuration this handler is for. */
- protected final BlazeCommandRunConfiguration configuration;
-
- @Nullable private BlazeCommandName command;
- @Nullable private String blazeBinary;
- private ImmutableList<String> blazeFlags = ImmutableList.of();
- private ImmutableList<String> exeFlags = ImmutableList.of();
+ private final String buildSystemName;
+ private final BlazeCommandRunConfigurationCommonState state;
public BlazeCommandGenericRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
- this.configuration = configuration;
+ this.buildSystemName = Blaze.buildSystemName(configuration.getProject());
+ this.state = new BlazeCommandRunConfigurationCommonState(buildSystemName);
}
- protected BlazeCommandGenericRunConfigurationHandler(
- BlazeCommandGenericRunConfigurationHandler other,
- BlazeCommandRunConfiguration configuration) {
- this(configuration);
- command = other.command;
- blazeFlags = other.blazeFlags;
- exeFlags = other.exeFlags;
- blazeBinary = other.blazeBinary;
+ @Override
+ public BlazeCommandRunConfigurationCommonState getState() {
+ return state;
}
- @Nullable
- public BlazeCommandName getCommand() {
- return command;
- }
-
- /** @return The list of blaze flags that the user specified manually. */
- public List<String> getBlazeFlags() {
- return blazeFlags;
- }
-
- /** @return The list of executable flags the user specified manually. */
- public List<String> getExeFlags() {
- return exeFlags;
- }
-
- /**
- * @return The list of all flags to be used on the Blaze command line for blaze. Subclasses should
- * override this method to add flags for higher-level settings (e.g. "run locally").
- */
- public List<String> getAllBlazeFlags() {
- return getBlazeFlags();
- }
-
- @Nullable
- public String getBlazeBinary() {
- return blazeBinary;
- }
-
- /**
- * @return The list of all flags to be used for the executable on the Blaze command line.
- * Subclasses should override this method to add flags if desired.
- */
- public List<String> getAllExeFlags() {
- return getExeFlags();
- }
-
- public void setCommand(@Nullable BlazeCommandName command) {
- this.command = command;
- }
-
- public final void setBlazeFlags(List<String> flags) {
- this.blazeFlags = ImmutableList.copyOf(flags);
- }
-
- public final void setExeFlags(List<String> flags) {
- this.exeFlags = ImmutableList.copyOf(flags);
- }
-
- public void setBlazeBinary(@Nullable String blazeBinary) {
- this.blazeBinary = blazeBinary;
- }
-
- /** Searches through all blaze flags for the first one beginning with '--test_filter' */
- @Nullable
- public String getTestFilterFlag() {
- for (String flag : getAllBlazeFlags()) {
- if (flag.startsWith(BlazeFlags.TEST_FILTER)) {
- return flag;
- }
- }
- return null;
+ @Override
+ public BlazeCommandRunConfigurationRunner createRunner(
+ Executor executor, ExecutionEnvironment environment) {
+ return new BlazeCommandGenericRunConfigurationRunner();
}
@Override
public void checkConfiguration() throws RuntimeConfigurationException {
- if (command == null) {
- throw new RuntimeConfigurationError("You must specify a command.");
- }
- if (blazeBinary != null && !(new File(blazeBinary).exists())) {
- throw new RuntimeConfigurationError(
- Blaze.buildSystemName(configuration.getProject()) + " binary does not exist");
- }
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- String commandString = element.getAttributeValue(COMMAND_ATTR);
- command =
- Strings.isNullOrEmpty(commandString) ? null : BlazeCommandName.fromString(commandString);
- blazeFlags = loadUserFlags(element, USER_BLAZE_FLAG_TAG);
- exeFlags = loadUserFlags(element, USER_EXE_FLAG_TAG);
- blazeBinary = element.getAttributeValue(BLAZE_BINARY_TAG);
- }
-
- private static ImmutableList<String> loadUserFlags(Element root, String tag) {
- ImmutableList.Builder<String> flagsBuilder = ImmutableList.builder();
- for (Element e : root.getChildren(tag)) {
- String flag = e.getTextTrim();
- if (flag != null && !flag.isEmpty()) {
- flagsBuilder.add(flag);
- }
- }
- return flagsBuilder.build();
- }
-
- @Override
- public void writeExternal(Element element) {
- if (command != null) {
- element.setAttribute(COMMAND_ATTR, command.toString());
- }
- saveUserFlags(element, blazeFlags, USER_BLAZE_FLAG_TAG);
- saveUserFlags(element, exeFlags, USER_EXE_FLAG_TAG);
- if (!Strings.isNullOrEmpty(blazeBinary)) {
- element.setAttribute(BLAZE_BINARY_TAG, blazeBinary);
- }
- }
-
- private static void saveUserFlags(Element root, List<String> flags, String tag) {
- for (String flag : flags) {
- Element child = new Element(tag);
- child.setText(flag);
- root.addContent(child);
- }
- }
-
- @Override
- public BlazeCommandGenericRunConfigurationHandler cloneFor(
- BlazeCommandRunConfiguration configuration) {
- return new BlazeCommandGenericRunConfigurationHandler(this, configuration);
- }
-
- @Override
- public RunProfileState getState(Executor executor, ExecutionEnvironment environment) {
- return new BlazeCommandGenericRunConfigurationHandler.BlazeCommandRunProfileState(environment);
- }
-
- @Override
- public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
- // Don't execute any tasks.
- return true;
+ state.validate(buildSystemName);
}
@Override
@Nullable
- public String suggestedName() {
+ public String suggestedName(BlazeCommandRunConfiguration configuration) {
if (configuration.getTarget() == null) {
return null;
}
@@ -244,15 +70,11 @@
@Override
@Nullable
public String getCommandName() {
+ BlazeCommandName command = state.getCommand();
return command != null ? command.toString() : null;
}
@Override
- public boolean isGeneratedName(boolean hasGeneratedFlag) {
- return hasGeneratedFlag;
- }
-
- @Override
public String getHandlerName() {
return "Generic Handler";
}
@@ -262,163 +84,4 @@
public Icon getExecutorIcon(RunConfiguration configuration, Executor executor) {
return null;
}
-
- @Override
- public BlazeCommandRunConfigurationHandlerEditor getHandlerEditor() {
- return new BlazeCommandGenericRunConfigurationHandler
- .BlazeCommandGenericRunConfigurationHandlerEditor(this);
- }
-
- /** {@link RunProfileState} for generic blaze commands. */
- private static class BlazeCommandRunProfileState extends CommandLineState {
- private final BlazeCommandRunConfiguration configuration;
- private final BlazeCommandGenericRunConfigurationHandler handler;
-
- BlazeCommandRunProfileState(ExecutionEnvironment environment) {
- super(environment);
- RunProfile runProfile = environment.getRunProfile();
- configuration = (BlazeCommandRunConfiguration) runProfile;
- handler = (BlazeCommandGenericRunConfigurationHandler) configuration.getHandler();
- }
-
- @Override
- @NotNull
- protected ProcessHandler startProcess() throws ExecutionException {
- Project project = configuration.getProject();
- BlazeImportSettings importSettings =
- BlazeImportSettingsManager.getInstance(project).getImportSettings();
- assert importSettings != null;
-
- ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
- assert projectViewSet != null;
-
- BlazeCommand blazeCommand =
- BlazeCommand.builder(Blaze.getBuildSystem(project), handler.getCommand())
- .setBlazeBinary(handler.getBlazeBinary())
- .addTargets(configuration.getTarget())
- .addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
- .addBlazeFlags(handler.getAllBlazeFlags())
- .addExeFlags(handler.getAllExeFlags())
- .build();
-
- WorkspaceRoot workspaceRoot = WorkspaceRoot.fromImportSettings(importSettings);
- return new ScopedBlazeProcessHandler(
- project,
- blazeCommand,
- workspaceRoot,
- new ScopedBlazeProcessHandler.ScopedProcessHandlerDelegate() {
- @Override
- public void onBlazeContextStart(BlazeContext context) {
- context
- .push(new LoggedTimingScope(project, Action.BLAZE_COMMAND_USAGE))
- .push(new IssuesScope(project))
- .push(new IdeaLogScope());
- }
-
- @Override
- public ImmutableList<ProcessListener> createProcessListeners(BlazeContext context) {
- LineProcessingOutputStream outputStream =
- LineProcessingOutputStream.of(
- new IssueOutputLineProcessor(project, context, workspaceRoot));
- return ImmutableList.of(new LineProcessingProcessAdapter(outputStream));
- }
- });
- }
- }
-
- /** {@link BlazeCommandRunConfigurationHandlerEditor} for generic blaze commands. */
- static class BlazeCommandGenericRunConfigurationHandlerEditor
- implements BlazeCommandRunConfigurationHandlerEditor {
- private final String buildSystemName;
-
- private final ComboBox commandCombo;
- private final JTextArea blazeFlagsField = new JTextArea(5, 1);
- private final JTextArea exeFlagsField = new JTextArea(5, 1);
- private final JBTextField blazeBinaryField = new JBTextField(1);
-
- public BlazeCommandGenericRunConfigurationHandlerEditor(
- BlazeCommandGenericRunConfigurationHandler handler) {
- buildSystemName = Blaze.buildSystemName(handler.configuration.getProject());
- commandCombo =
- new ComboBox(new DefaultComboBoxModel(BlazeCommandName.knownCommands().toArray()));
- // Allow the user to manually specify an unlisted command.
- commandCombo.setEditable(true);
- blazeBinaryField.getEmptyText().setText("(Use global)");
- }
-
- private static String makeArgString(List<String> arguments) {
- StringBuilder flagString = new StringBuilder();
- for (String flag : arguments) {
- if (flagString.length() > 0) {
- flagString.append('\n');
- }
- if (flag.isEmpty() || flag.contains(" ") || flag.contains("|")) {
- flagString.append('"');
- flagString.append(flag);
- flagString.append('"');
- } else {
- flagString.append(flag);
- }
- }
- return flagString.toString();
- }
-
- @Override
- public void resetEditorFrom(BlazeCommandRunConfigurationHandler h) {
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) h;
-
- commandCombo.setSelectedItem(handler.command);
-
- // Normally we could just use ParametersListUtils.join, but that will only space-delimit args
- blazeFlagsField.setText(makeArgString(handler.getBlazeFlags()));
- exeFlagsField.setText(makeArgString(handler.getExeFlags()));
-
- blazeBinaryField.setText(Strings.nullToEmpty(handler.blazeBinary));
- }
-
- @Override
- public void applyEditorTo(BlazeCommandRunConfigurationHandler h) {
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) h;
- Object selectedCommand = commandCombo.getSelectedItem();
- if (selectedCommand instanceof BlazeCommandName) {
- handler.command = (BlazeCommandName) selectedCommand;
- } else {
- handler.command =
- Strings.isNullOrEmpty((String) selectedCommand)
- ? null
- : BlazeCommandName.fromString(selectedCommand.toString());
- }
- handler.blazeFlags =
- ImmutableList.copyOf(
- ParametersListUtil.parse(Strings.nullToEmpty(blazeFlagsField.getText())));
- handler.exeFlags =
- ImmutableList.copyOf(
- ParametersListUtil.parse(Strings.nullToEmpty(exeFlagsField.getText())));
-
- String blazeBinary = blazeBinaryField.getText();
- handler.blazeBinary = Strings.emptyToNull(blazeBinary);
- }
-
- @Override
- @NotNull
- public JComponent createEditor() {
- return UiUtil.createBox(
- new JLabel(buildSystemName + " command:"),
- commandCombo,
- new JLabel(buildSystemName + " flags:"),
- new JScrollPane(
- blazeFlagsField,
- JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
- ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED),
- new JLabel("Executable flags:"),
- new JScrollPane(
- exeFlagsField,
- JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
- ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED),
- new JLabel(buildSystemName + " binary:"),
- blazeBinaryField);
- }
- }
}
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
new file mode 100644
index 0000000..ed40a0d
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationRunner.java
@@ -0,0 +1,124 @@
+/*
+ * 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.run.confighandler;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
+import com.google.idea.blaze.base.command.BlazeCommand;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
+import com.google.idea.blaze.base.metrics.Action;
+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.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.processhandler.LineProcessingProcessAdapter;
+import com.google.idea.blaze.base.run.processhandler.ScopedBlazeProcessHandler;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.scope.scopes.IdeaLogScope;
+import com.google.idea.blaze.base.scope.scopes.IssuesScope;
+import com.google.idea.blaze.base.scope.scopes.LoggedTimingScope;
+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.intellij.execution.ExecutionException;
+import com.intellij.execution.Executor;
+import com.intellij.execution.configurations.CommandLineState;
+import com.intellij.execution.configurations.RunProfile;
+import com.intellij.execution.configurations.RunProfileState;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.process.ProcessListener;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Generic runner for {@link BlazeCommandRunConfiguration}s, used as a fallback in the case where no
+ * other runners are more relevant.
+ */
+public final class BlazeCommandGenericRunConfigurationRunner
+ implements BlazeCommandRunConfigurationRunner {
+
+ @Override
+ public RunProfileState getRunProfileState(Executor executor, ExecutionEnvironment environment) {
+ return new BlazeCommandRunProfileState(environment);
+ }
+
+ @Override
+ public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
+ // Don't execute any tasks.
+ return true;
+ }
+
+ /** {@link RunProfileState} for generic blaze commands. */
+ private static class BlazeCommandRunProfileState extends CommandLineState {
+ private final BlazeCommandRunConfiguration configuration;
+ private final BlazeCommandRunConfigurationCommonState handlerState;
+
+ BlazeCommandRunProfileState(ExecutionEnvironment environment) {
+ super(environment);
+ RunProfile runProfile = environment.getRunProfile();
+ configuration = (BlazeCommandRunConfiguration) runProfile;
+ handlerState =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
+ }
+
+ @Override
+ @NotNull
+ protected ProcessHandler startProcess() throws ExecutionException {
+ Project project = configuration.getProject();
+ BlazeImportSettings importSettings =
+ BlazeImportSettingsManager.getInstance(project).getImportSettings();
+ assert importSettings != null;
+
+ ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
+ assert projectViewSet != null;
+
+ BlazeCommand blazeCommand =
+ BlazeCommand.builder(Blaze.getBuildSystem(project), handlerState.getCommand())
+ .setBlazeBinary(handlerState.getBlazeBinary())
+ .addTargets(configuration.getTarget())
+ .addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
+ .addBlazeFlags(handlerState.getBlazeFlags())
+ .addExeFlags(handlerState.getExeFlags())
+ .build();
+
+ WorkspaceRoot workspaceRoot = WorkspaceRoot.fromImportSettings(importSettings);
+ return new ScopedBlazeProcessHandler(
+ project,
+ blazeCommand,
+ workspaceRoot,
+ new ScopedBlazeProcessHandler.ScopedProcessHandlerDelegate() {
+ @Override
+ public void onBlazeContextStart(BlazeContext context) {
+ context
+ .push(new LoggedTimingScope(project, Action.BLAZE_COMMAND_USAGE))
+ .push(new IssuesScope(project))
+ .push(new IdeaLogScope());
+ }
+
+ @Override
+ public ImmutableList<ProcessListener> createProcessListeners(BlazeContext context) {
+ LineProcessingOutputStream outputStream =
+ LineProcessingOutputStream.of(
+ new IssueOutputLineProcessor(project, context, workspaceRoot));
+ return ImmutableList.of(new LineProcessingProcessAdapter(outputStream));
+ }
+ });
+ }
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandler.java b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandler.java
index 7d88a7e..0e21967 100644
--- a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandler.java
+++ b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandler.java
@@ -16,25 +16,29 @@
package com.google.idea.blaze.base.run.confighandler;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.state.RunConfigurationState;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.WriteExternalException;
import javax.annotation.Nullable;
import javax.swing.Icon;
-import org.jdom.Element;
/**
* Supports the run configuration flow for {@link BlazeCommandRunConfiguration}s.
*
- * <p>Provides rule-specific configuration state, editor, name, RunProfileState, and
- * before-run-tasks.
+ * <p>Provides rule-specific configuration state, validation, presentation, and runner.
*/
public interface BlazeCommandRunConfigurationHandler {
+ RunConfigurationState getState();
+
+
+
+ /** @return A {@link BlazeCommandRunConfigurationRunner} for running the configuration. */
+ @Nullable
+ BlazeCommandRunConfigurationRunner createRunner(
+ Executor executor, ExecutionEnvironment environment) throws ExecutionException;
/**
* Checks whether the handler settings are valid.
@@ -43,50 +47,12 @@
*/
void checkConfiguration() throws RuntimeConfigurationException;
- /** Loads this handler's state from the external data. */
- void readExternal(Element element) throws InvalidDataException;
-
- /** Writes this handler's state to the element. */
- @SuppressWarnings("ThrowsUncheckedException")
- void writeExternal(Element element) throws WriteExternalException;
-
- /**
- * Creates a clone of this handler for the specified configuration.
- *
- * @return A new BlazeCommandRunConfigurationHandler with the same state as this one, except its
- * configuration is the specified {@code configuration}.
- */
- BlazeCommandRunConfigurationHandler cloneFor(BlazeCommandRunConfiguration configuration);
-
- /** @return the RunProfileState corresponding to the given environment. */
- RunProfileState getState(Executor executor, ExecutionEnvironment environment)
- throws ExecutionException;
-
- /**
- * Executes any required before run tasks.
- *
- * @return true if no task exists or the task was successfully completed. Otherwise returns false
- * if the task either failed or was cancelled.
- */
- boolean executeBeforeRunTask(ExecutionEnvironment environment);
-
/**
* @return The default name of the run configuration based on its settings and this handler's
* state.
*/
@Nullable
- String suggestedName();
-
- /**
- * Allows overriding the default behavior of {@link
- * com.intellij.execution.configurations.LocatableConfiguration#isGeneratedName()}. Return {@code
- * hasGeneratedFlag} to keep the default behavior.
- *
- * @param hasGeneratedFlag Whether the configuration reports its name is generated.
- * @return Whether the run configuration's name should be treated as generated (allowing
- * regenerating it when settings change).
- */
- boolean isGeneratedName(boolean hasGeneratedFlag);
+ String suggestedName(BlazeCommandRunConfiguration configuration);
/**
* @return The name of the Blaze command associated with this handler. May be null if no command
@@ -105,7 +71,4 @@
*/
@Nullable
Icon getExecutorIcon(RunConfiguration configuration, Executor executor);
-
- /** @return A {@link BlazeCommandRunConfigurationHandlerEditor} for this handler. */
- BlazeCommandRunConfigurationHandlerEditor getHandlerEditor();
}
diff --git a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandlerEditor.java b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandlerEditor.java
deleted file mode 100644
index 0c9bce7..0000000
--- a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandlerEditor.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.base.run.confighandler;
-
-import javax.swing.JComponent;
-import org.jetbrains.annotations.Nullable;
-
-/** Provides support for editing {@link BlazeCommandRunConfigurationHandler}s. */
-public interface BlazeCommandRunConfigurationHandlerEditor {
- /** Reset the editor based on the state of the given handler. */
- void resetEditorFrom(BlazeCommandRunConfigurationHandler handler);
-
- /** Update the given handler's state based on the editor. */
- void applyEditorTo(BlazeCommandRunConfigurationHandler handler);
-
- /** @return A component to display for the editor. */
- @Nullable
- JComponent createEditor();
-}
diff --git a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandlerProvider.java b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandlerProvider.java
index af67362..648f2c3 100644
--- a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandlerProvider.java
+++ b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationHandlerProvider.java
@@ -40,10 +40,8 @@
return handlerProvider;
}
}
- // BlazeCommandGenericRunConfigurationHandlerProvider can handle any kind,
- // and will be returned by this point.
- assert false;
- return null;
+ throw new RuntimeException(
+ "No BlazeCommandRunConfigurationHandlerProvider found for Kind " + kind);
}
/** Get the BlazeCommandRunConfigurationHandlerProvider with the given ID, if one exists. */
@@ -61,7 +59,7 @@
boolean canHandleKind(Kind kind);
/** Returns the corresponding {@link BlazeCommandRunConfigurationHandler}. */
- BlazeCommandRunConfigurationHandler createHandler(BlazeCommandRunConfiguration config);
+ BlazeCommandRunConfigurationHandler createHandler(BlazeCommandRunConfiguration configuration);
/**
* Returns the unique ID of this {@link BlazeCommandRunConfigurationHandlerProvider}. The ID is
diff --git a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationRunner.java b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationRunner.java
new file mode 100644
index 0000000..bf0dd6f
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeCommandRunConfigurationRunner.java
@@ -0,0 +1,45 @@
+/*
+ * 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.run.confighandler;
+
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.Executor;
+import com.intellij.execution.configurations.RunProfileState;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.openapi.util.Key;
+
+/**
+ * Supports the execution of {@link BlazeCommandRunConfiguration}s.
+ *
+ * <p>Provides rule-specific RunProfileState and before-run-tasks.
+ */
+public interface BlazeCommandRunConfigurationRunner {
+ /** Used to store a runner to an {@link ExecutionEnvironment}. */
+ Key<BlazeCommandRunConfigurationRunner> RUNNER_KEY = Key.create("blaze.run.config.runner");
+
+ /** @return the RunProfileState corresponding to the given environment. */
+ RunProfileState getRunProfileState(Executor executor, ExecutionEnvironment environment)
+ throws ExecutionException;
+
+ /**
+ * Executes any required before run tasks.
+ *
+ * @return true if no task exists or the task was successfully completed. Otherwise returns false
+ * if the task either failed or was cancelled.
+ */
+ boolean executeBeforeRunTask(ExecutionEnvironment environment);
+}
diff --git a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeUnknownRunConfigurationHandler.java b/base/src/com/google/idea/blaze/base/run/confighandler/BlazeUnknownRunConfigurationHandler.java
deleted file mode 100644
index e968860..0000000
--- a/base/src/com/google/idea/blaze/base/run/confighandler/BlazeUnknownRunConfigurationHandler.java
+++ /dev/null
@@ -1,158 +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.run.confighandler;
-
-import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
-import com.google.idea.blaze.base.settings.Blaze;
-import com.intellij.execution.ExecutionException;
-import com.intellij.execution.Executor;
-import com.intellij.execution.configurations.RunConfiguration;
-import com.intellij.execution.configurations.RunProfileState;
-import com.intellij.execution.configurations.RuntimeConfigurationException;
-import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.util.InvalidDataException;
-import java.util.HashSet;
-import java.util.Set;
-import javax.annotation.Nullable;
-import javax.swing.Icon;
-import javax.swing.JComponent;
-import org.jdom.Attribute;
-import org.jdom.Element;
-
-/**
- * Fallback handler for {@link BlazeCommandRunConfiguration}s with uninitialized targets or unknown
- * handler providers.
- *
- * <p>Cannot be run and provides no editor. Writes all attributes and elements it initially read,
- * except those with names matching existing content written by the configuration itself.
- */
-public class BlazeUnknownRunConfigurationHandler implements BlazeCommandRunConfigurationHandler {
-
- private final BlazeCommandRunConfiguration configuration;
-
- @Nullable private Element externalElementBackup;
-
- public BlazeUnknownRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
- this.configuration = configuration;
- }
-
- @Override
- public void checkConfiguration() throws RuntimeConfigurationException {
- // No need to throw anything here; BlazeCommandRunConfiguration's
- // check will already detect any config with this handler as invalid
- // because its provider is null and all targets are handled by some provider.
- assert false;
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- externalElementBackup = element.clone();
- }
-
- @Override
- public void writeExternal(Element element) {
- // Write back attributes and elements from externalElementBackup,
- // but take care not to write any which exist in the passed element.
- // Such attributes and elements belong to the configuration, not the handler!
- if (externalElementBackup != null) {
- Set<String> configurationAttributeNames = new HashSet<>();
- for (Attribute attribute : element.getAttributes()) {
- configurationAttributeNames.add(attribute.getName());
- }
- Set<String> configurationElementNames = new HashSet<>();
- for (Element child : element.getChildren()) {
- configurationElementNames.add(child.getName());
- }
-
- for (Attribute attribute : externalElementBackup.getAttributes()) {
- if (!configurationAttributeNames.contains(attribute.getName())) {
- element.setAttribute(attribute.clone());
- }
- }
- for (Element child : externalElementBackup.getChildren()) {
- if (!configurationElementNames.contains(child.getName())) {
- element.addContent(child.clone());
- }
- }
- }
- }
-
- @Override
- public BlazeUnknownRunConfigurationHandler cloneFor(BlazeCommandRunConfiguration configuration) {
- return new BlazeUnknownRunConfigurationHandler(configuration);
- }
-
- @Override
- public RunProfileState getState(Executor executor, ExecutionEnvironment environment)
- throws ExecutionException {
- return null;
- }
-
- @Override
- public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
- return true;
- }
-
- @Nullable
- @Override
- public String suggestedName() {
- return String.format(
- "Unknown %s Configuration", Blaze.buildSystemName(configuration.getProject()));
- }
-
- @Override
- public boolean isGeneratedName(boolean hasGeneratedFlag) {
- return hasGeneratedFlag;
- }
-
- @Nullable
- @Override
- public String getCommandName() {
- return null;
- }
-
- @Override
- public String getHandlerName() {
- return "no handler";
- }
-
- @Override
- @Nullable
- public Icon getExecutorIcon(RunConfiguration configuration, Executor executor) {
- return null;
- }
-
- @Override
- public BlazeCommandRunConfigurationHandlerEditor getHandlerEditor() {
- return new BlazeCommandRunConfigurationHandlerEditor() {
- @Override
- public void resetEditorFrom(BlazeCommandRunConfigurationHandler handler) {}
-
- @Override
- public void applyEditorTo(BlazeCommandRunConfigurationHandler handler) {}
-
- @Override
- @Nullable
- public JComponent createEditor() {
- // Note: currently this will never be displayed,
- // as the handler editor is not shown for invalidated configurations.
- //return new JBLabel("Configuration could not be loaded "
- // + "because its handler could not be found.");
- return null;
- }
- };
- }
-}
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 e3746f3..154a9be 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
@@ -21,7 +21,7 @@
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
@@ -56,12 +56,12 @@
sourceElement.set(dir);
configuration.setTarget(TargetExpression.allFromPackageRecursive(packagePath));
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
return false;
}
- handler.setCommand(BlazeCommandName.TEST);
+ handlerState.setCommand(BlazeCommandName.TEST);
configuration.setGeneratedName();
return true;
}
@@ -79,12 +79,12 @@
if (packagePath == null) {
return false;
}
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
return false;
}
- return Objects.equals(handler.getCommand(), BlazeCommandName.TEST)
+ return Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)
&& Objects.equals(
configuration.getTarget(), TargetExpression.allFromPackageRecursive(packagePath));
}
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 a28b644..aa00460 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
@@ -16,18 +16,19 @@
package com.google.idea.blaze.base.run.producers;
import com.google.idea.blaze.base.command.BlazeCommandName;
-import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
import com.google.idea.blaze.base.lang.buildfile.psi.FuncallExpression;
+import com.google.idea.blaze.base.lang.buildfile.references.BuildReferenceManager;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.BlazeRuleConfigurationFactory;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
-import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
+import com.google.idea.blaze.base.run.BlazeRunConfigurationFactory;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
-import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -38,18 +39,18 @@
public class BlazeBuildFileRunConfigurationProducer
extends BlazeRunConfigurationProducer<BlazeCommandRunConfiguration> {
+ private static final Logger LOG =
+ Logger.getInstance(BlazeBuildFileRunConfigurationProducer.class);
+
private static class BuildTarget {
private final FuncallExpression rule;
private final String ruleType;
private final Label label;
- @Nullable private final RuleIdeInfo ruleIdeInfo;
- public BuildTarget(
- FuncallExpression rule, String ruleType, Label label, @Nullable RuleIdeInfo ruleIdeInfo) {
+ BuildTarget(FuncallExpression rule, String ruleType, Label label) {
this.rule = rule;
this.ruleType = ruleType;
this.label = label;
- this.ruleIdeInfo = ruleIdeInfo;
}
}
@@ -67,14 +68,12 @@
if (blazeProjectData == null) {
return false;
}
- WorkspaceLanguageSettings workspaceLanguageSettings =
- blazeProjectData.workspaceLanguageSettings;
BuildTarget target = getBuildTarget(context);
if (target == null) {
return false;
}
sourceElement.set(target.rule);
- setupConfiguration(configuration, workspaceLanguageSettings, target);
+ setupConfiguration(configuration.getProject(), blazeProjectData, configuration, target);
return true;
}
@@ -88,7 +87,6 @@
if (!Objects.equals(configuration.getTarget(), target.label)) {
return false;
}
-
// We don't know any details about how the various factories set up configurations from here.
// Simply returning true at this point would be overly broad
// (all configs with a matching target would be identified).
@@ -105,23 +103,21 @@
if (blazeProjectData == null) {
return false;
}
- WorkspaceLanguageSettings workspaceLanguageSettings =
- blazeProjectData.workspaceLanguageSettings;
BlazeCommandRunConfiguration generatedConfiguration =
new BlazeCommandRunConfiguration(
configuration.getProject(), configuration.getFactory(), configuration.getName());
- setupConfiguration(generatedConfiguration, workspaceLanguageSettings, target);
+ setupConfiguration(
+ configuration.getProject(), blazeProjectData, generatedConfiguration, target);
// TODO This check should be removed once isTestRule is in a RuleFactory and
// test rules' suggestedName is modified to account for test filter flags.
if (isTestRule(target.ruleType)) {
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler != null && handler.getTestFilterFlag() != null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState != null && handlerState.getTestFilterFlag() != null) {
return false;
}
}
- // End-TODO
return Objects.equals(configuration.suggestedName(), generatedConfiguration.suggestedName())
&& Objects.equals(
@@ -129,10 +125,27 @@
generatedConfiguration.getHandler().getCommandName());
}
+ public static boolean handlesTarget(Project project, Label label) {
+ return buildTargetFromLabel(project, label) != null;
+ }
+
+ @Nullable
+ private static BuildTarget buildTargetFromLabel(Project project, Label label) {
+ PsiElement psiElement = BuildReferenceManager.getInstance(project).resolveLabel(label);
+ if (!(psiElement instanceof FuncallExpression)) {
+ return null;
+ }
+ return targetFromFuncall((FuncallExpression) psiElement);
+ }
+
@Nullable
private static BuildTarget getBuildTarget(ConfigurationContext context) {
- FuncallExpression rule =
- PsiTreeUtil.getNonStrictParentOfType(context.getPsiLocation(), FuncallExpression.class);
+ return targetFromFuncall(
+ PsiTreeUtil.getNonStrictParentOfType(context.getPsiLocation(), FuncallExpression.class));
+ }
+
+ @Nullable
+ private static BuildTarget targetFromFuncall(@Nullable FuncallExpression rule) {
if (rule == null) {
return null;
}
@@ -141,40 +154,52 @@
if (ruleType == null || label == null) {
return null;
}
- RuleIdeInfo ruleIdeInfo = RuleFinder.getInstance().ruleForTarget(context.getProject(), label);
- return new BuildTarget(rule, ruleType, label, ruleIdeInfo);
+ return new BuildTarget(rule, ruleType, label);
+ }
+
+ public static void setupConfiguration(RunConfiguration configuration, Label label) {
+ BuildTarget target = buildTargetFromLabel(configuration.getProject(), label);
+ if (target == null || !(configuration instanceof BlazeCommandRunConfiguration)) {
+ LOG.error("Configuration not handled by BUILD file config producer: " + configuration);
+ return;
+ }
+ setupBuildFileConfiguration((BlazeCommandRunConfiguration) configuration, target);
}
private static void setupConfiguration(
+ Project project,
+ BlazeProjectData blazeProjectData,
BlazeCommandRunConfiguration configuration,
- WorkspaceLanguageSettings workspaceLanguageSettings,
BuildTarget target) {
- // First see if a BlazeRuleConfigurationFactory can give us a specialized setup.
- if (target.ruleIdeInfo != null) {
- for (BlazeRuleConfigurationFactory configurationFactory :
- BlazeRuleConfigurationFactory.EP_NAME.getExtensions()) {
- if (configurationFactory.handlesRule(workspaceLanguageSettings, target.ruleIdeInfo)
- && configurationFactory.handlesConfiguration(configuration)) {
- configurationFactory.setupConfiguration(configuration, target.ruleIdeInfo);
- return;
- }
+ // First see if a BlazeRunConfigurationFactory can give us a specialized setup.
+ for (BlazeRunConfigurationFactory configurationFactory :
+ BlazeRunConfigurationFactory.EP_NAME.getExtensions()) {
+ if (configurationFactory.handlesTarget(project, blazeProjectData, target.label)
+ && configurationFactory.handlesConfiguration(configuration)) {
+ configurationFactory.setupConfiguration(configuration, target.label);
+ return;
}
}
// If no factory exists, directly set up the configuration.
+ setupBuildFileConfiguration(configuration, target);
+ }
+
+ private static void setupBuildFileConfiguration(
+ BlazeCommandRunConfiguration configuration, BuildTarget target) {
configuration.setTarget(target.label);
// Try to make it a 'blaze build' command, if applicable.
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler != null) {
- // TODO move the old test rule functionality to a BlazeRuleConfigurationFactory
- handler.setCommand(
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState != null) {
+ // TODO move the old test rule functionality to a BlazeRunConfigurationFactory
+ handlerState.setCommand(
isTestRule(target.ruleType) ? BlazeCommandName.TEST : BlazeCommandName.BUILD);
}
configuration.setGeneratedName();
}
- // TODO this functionality should be moved to a BlazeRuleConfigurationFactory
+ // TODO this functionality should be moved to a BlazeRunConfigurationFactory
private static boolean isTestRule(String ruleType) {
return isTestSuite(ruleType) || ruleType.endsWith("_test");
}
diff --git a/base/src/com/google/idea/blaze/base/run/rulefinder/RuleFinder.java b/base/src/com/google/idea/blaze/base/run/rulefinder/RuleFinder.java
index 1b1b858..1e48ec0 100644
--- a/base/src/com/google/idea/blaze/base/run/rulefinder/RuleFinder.java
+++ b/base/src/com/google/idea/blaze/base/run/rulefinder/RuleFinder.java
@@ -35,7 +35,7 @@
@Nullable
public RuleIdeInfo ruleForTarget(Project project, final Label target) {
- return findRule(project, input -> input.label.equals(target));
+ return findRule(project, rule -> rule.label.equals(target));
}
public ImmutableList<RuleIdeInfo> rulesOfKinds(Project project, final Kind... kinds) {
@@ -43,7 +43,7 @@
}
public ImmutableList<RuleIdeInfo> rulesOfKinds(Project project, final List<Kind> kinds) {
- return ImmutableList.copyOf(findRules(project, input -> input.kindIsOneOf(kinds)));
+ return ImmutableList.copyOf(findRules(project, rule -> rule.kindIsOneOf(kinds)));
}
@Nullable
diff --git a/base/src/com/google/idea/blaze/base/run/state/BlazeBinaryState.java b/base/src/com/google/idea/blaze/base/run/state/BlazeBinaryState.java
new file mode 100644
index 0000000..2ddeffc
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/state/BlazeBinaryState.java
@@ -0,0 +1,91 @@
+/*
+ * 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.run.state;
+
+import com.google.common.base.Strings;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.ui.UiUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.components.JBTextField;
+import javax.annotation.Nullable;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import org.jdom.Element;
+
+/** State for a Blaze binary to run configurations with. */
+public final class BlazeBinaryState implements RunConfigurationState {
+ private static final String BLAZE_BINARY_ATTR = "blaze-binary";
+
+ @Nullable private String blazeBinary;
+
+ public BlazeBinaryState() {}
+
+ @Nullable
+ public String getBlazeBinary() {
+ return blazeBinary;
+ }
+
+ public void setBlazeBinary(@Nullable String blazeBinary) {
+ this.blazeBinary = blazeBinary;
+ }
+
+ @Override
+ public void readExternal(Element element) {
+ blazeBinary = element.getAttributeValue(BLAZE_BINARY_ATTR);
+ }
+
+ @Override
+ public void writeExternal(Element element) {
+ if (!Strings.isNullOrEmpty(blazeBinary)) {
+ element.setAttribute(BLAZE_BINARY_ATTR, blazeBinary);
+ } else {
+ element.removeAttribute(BLAZE_BINARY_ATTR);
+ }
+ }
+
+ @Override
+ public RunConfigurationStateEditor getEditor(Project project) {
+ return new BlazeBinaryStateEditor(project);
+ }
+
+ private static class BlazeBinaryStateEditor implements RunConfigurationStateEditor {
+ private final String buildSystemName;
+
+ private final JBTextField blazeBinaryField = new JBTextField(1);
+
+ BlazeBinaryStateEditor(Project project) {
+ buildSystemName = Blaze.buildSystemName(project);
+ blazeBinaryField.getEmptyText().setText("(Use global)");
+ }
+
+ @Override
+ public void resetEditorFrom(RunConfigurationState genericState) {
+ BlazeBinaryState state = (BlazeBinaryState) genericState;
+ blazeBinaryField.setText(Strings.nullToEmpty(state.getBlazeBinary()));
+ }
+
+ @Override
+ public void applyEditorTo(RunConfigurationState genericState) {
+ BlazeBinaryState state = (BlazeBinaryState) genericState;
+ state.setBlazeBinary(Strings.emptyToNull(blazeBinaryField.getText()));
+ }
+
+ @Override
+ public JComponent createComponent() {
+ return UiUtil.createBox(new JLabel(buildSystemName + " binary:"), blazeBinaryField);
+ }
+ }
+}
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
new file mode 100644
index 0000000..ab44e47
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonState.java
@@ -0,0 +1,103 @@
+/*
+ * 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.run.state;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.intellij.execution.configurations.RuntimeConfigurationError;
+import com.intellij.execution.configurations.RuntimeConfigurationException;
+import java.io.File;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/**
+ * Shared state common to several {@link
+ * com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler} types.
+ */
+public final class BlazeCommandRunConfigurationCommonState extends RunConfigurationCompositeState {
+ private static final String USER_BLAZE_FLAG_TAG = "blaze-user-flag";
+ private static final String USER_EXE_FLAG_TAG = "blaze-user-exe-flag";
+
+ private final BlazeCommandState command;
+ private final RunConfigurationFlagsState blazeFlags;
+ private final RunConfigurationFlagsState exeFlags;
+ private final BlazeBinaryState blazeBinary;
+
+ public BlazeCommandRunConfigurationCommonState(String buildSystemName) {
+ command = new BlazeCommandState();
+ blazeFlags = new RunConfigurationFlagsState(USER_BLAZE_FLAG_TAG, buildSystemName + " flags:");
+ exeFlags = new RunConfigurationFlagsState(USER_EXE_FLAG_TAG, "Executable flags:");
+ blazeBinary = new BlazeBinaryState();
+ addStates(command, blazeFlags, exeFlags, blazeBinary);
+ }
+
+ @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();
+ }
+
+ /** @return The list of executable flags the user specified manually. */
+ public List<String> getExeFlags() {
+ return exeFlags.getFlags();
+ }
+
+ @Nullable
+ public String getBlazeBinary() {
+ return blazeBinary.getBlazeBinary();
+ }
+
+ public void setCommand(@Nullable BlazeCommandName command) {
+ this.command.setCommand(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);
+ }
+
+ /** Searches through all blaze flags for the first one beginning with '--test_filter' */
+ @Nullable
+ public String getTestFilterFlag() {
+ for (String flag : getBlazeFlags()) {
+ if (flag.startsWith(BlazeFlags.TEST_FILTER)) {
+ return flag;
+ }
+ }
+ return null;
+ }
+
+ public void validate(String buildSystemName) throws RuntimeConfigurationException {
+ if (getCommand() == null) {
+ throw new RuntimeConfigurationError("You must specify a command.");
+ }
+ String blazeBinaryString = getBlazeBinary();
+ if (blazeBinaryString != null && !(new File(blazeBinaryString).exists())) {
+ throw new RuntimeConfigurationError(buildSystemName + " binary does not exist");
+ }
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/run/state/BlazeCommandState.java b/base/src/com/google/idea/blaze/base/run/state/BlazeCommandState.java
new file mode 100644
index 0000000..491acb7
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/state/BlazeCommandState.java
@@ -0,0 +1,106 @@
+/*
+ * 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.run.state;
+
+import com.google.common.base.Strings;
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.ui.UiUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.ComboBox;
+import javax.annotation.Nullable;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import org.jdom.Element;
+
+/** State for a {@link BlazeCommandName}. */
+public final class BlazeCommandState implements RunConfigurationState {
+ private static final String COMMAND_ATTR = "blaze-command";
+
+ @Nullable private BlazeCommandName command;
+
+ public BlazeCommandState() {}
+
+ @Nullable
+ public BlazeCommandName getCommand() {
+ return command;
+ }
+
+ public void setCommand(@Nullable BlazeCommandName command) {
+ this.command = command;
+ }
+
+ @Override
+ public void readExternal(Element element) {
+ String commandString = element.getAttributeValue(COMMAND_ATTR);
+ command =
+ Strings.isNullOrEmpty(commandString) ? null : BlazeCommandName.fromString(commandString);
+ }
+
+ @Override
+ public void writeExternal(Element element) {
+ if (command != null) {
+ element.setAttribute(COMMAND_ATTR, command.toString());
+ } else {
+ element.removeAttribute(COMMAND_ATTR);
+ }
+ }
+
+ @Override
+ public RunConfigurationStateEditor getEditor(Project project) {
+ return new BlazeCommandStateEditor(project);
+ }
+
+ private static class BlazeCommandStateEditor implements RunConfigurationStateEditor {
+ private final String buildSystemName;
+
+ private final ComboBox commandCombo;
+
+ BlazeCommandStateEditor(Project project) {
+ buildSystemName = Blaze.buildSystemName(project);
+ commandCombo =
+ new ComboBox(new DefaultComboBoxModel<>(BlazeCommandName.knownCommands().toArray()));
+ // Allow the user to manually specify an unlisted command.
+ commandCombo.setEditable(true);
+ }
+
+ @Override
+ public void resetEditorFrom(RunConfigurationState genericState) {
+ BlazeCommandState state = (BlazeCommandState) genericState;
+ commandCombo.setSelectedItem(state.getCommand());
+ }
+
+ @Override
+ public void applyEditorTo(RunConfigurationState genericState) {
+ BlazeCommandState state = (BlazeCommandState) genericState;
+ Object selectedCommand = commandCombo.getSelectedItem();
+ if (selectedCommand instanceof BlazeCommandName) {
+ state.setCommand((BlazeCommandName) selectedCommand);
+ } else {
+ state.setCommand(
+ Strings.isNullOrEmpty((String) selectedCommand)
+ ? null
+ : BlazeCommandName.fromString(selectedCommand.toString()));
+ }
+ }
+
+ @Override
+ public JComponent createComponent() {
+ return UiUtil.createBox(new JLabel(buildSystemName + " command:"), commandCombo);
+ }
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/run/state/RunConfigurationCompositeState.java b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationCompositeState.java
new file mode 100644
index 0000000..077e02d
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationCompositeState.java
@@ -0,0 +1,100 @@
+/*
+ * 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.run.state;
+
+import com.google.common.collect.Lists;
+import com.google.idea.blaze.base.ui.UiUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.swing.JComponent;
+import org.jdom.Element;
+
+/** Helper class for managing composite state. */
+public class RunConfigurationCompositeState implements RunConfigurationState {
+ private final List<RunConfigurationState> states;
+
+ public RunConfigurationCompositeState(List<RunConfigurationState> states) {
+ this.states = states;
+ }
+
+ protected RunConfigurationCompositeState() {
+ this.states = Lists.newArrayList();
+ }
+
+ protected void addStates(RunConfigurationState... states) {
+ Collections.addAll(this.states, states);
+ }
+
+ @Override
+ public final void readExternal(Element element) throws InvalidDataException {
+ for (RunConfigurationState state : states) {
+ state.readExternal(element);
+ }
+ }
+
+ /** Updates the element with the handler's state. */
+ @Override
+ @SuppressWarnings("ThrowsUncheckedException")
+ public final void writeExternal(Element element) throws WriteExternalException {
+ for (RunConfigurationState state : states) {
+ state.writeExternal(element);
+ }
+ }
+
+ /** @return A {@link RunConfigurationStateEditor} for this state. */
+ @Override
+ public final RunConfigurationStateEditor getEditor(Project project) {
+ return new RunConfigurationCompositeStateEditor(project, states);
+ }
+
+ private static class RunConfigurationCompositeStateEditor implements RunConfigurationStateEditor {
+ List<RunConfigurationStateEditor> editors;
+
+ public RunConfigurationCompositeStateEditor(
+ Project project, List<RunConfigurationState> states) {
+ editors = states.stream().map(state -> state.getEditor(project)).collect(Collectors.toList());
+ }
+
+ @Override
+ public void resetEditorFrom(RunConfigurationState genericState) {
+ RunConfigurationCompositeState state = (RunConfigurationCompositeState) genericState;
+ for (int i = 0; i < editors.size(); ++i) {
+ editors.get(i).resetEditorFrom(state.states.get(i));
+ }
+ }
+
+ @Override
+ public void applyEditorTo(RunConfigurationState genericState) {
+ RunConfigurationCompositeState state = (RunConfigurationCompositeState) genericState;
+ for (int i = 0; i < editors.size(); ++i) {
+ editors.get(i).applyEditorTo(state.states.get(i));
+ }
+ }
+
+ @Override
+ public JComponent createComponent() {
+ return UiUtil.createBox(
+ editors
+ .stream()
+ .map(RunConfigurationStateEditor::createComponent)
+ .collect(Collectors.toList()));
+ }
+ }
+}
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
new file mode 100644
index 0000000..c0edaa4
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationFlagsState.java
@@ -0,0 +1,128 @@
+/*
+ * 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.run.state;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.ui.UiUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.execution.ParametersListUtil;
+import java.util.List;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.ScrollPaneConstants;
+import org.jdom.Element;
+
+/** State for a list of user-defined flags. */
+public final class RunConfigurationFlagsState implements RunConfigurationState {
+
+ private final String tag;
+ private final String fieldLabel;
+
+ private ImmutableList<String> flags = ImmutableList.of();
+
+ public RunConfigurationFlagsState(String tag, String fieldLabel) {
+ this.tag = tag;
+ this.fieldLabel = fieldLabel;
+ }
+
+ public List<String> getFlags() {
+ return flags;
+ }
+
+ public void setFlags(List<String> flags) {
+ this.flags = ImmutableList.copyOf(flags);
+ }
+
+ @Override
+ public void readExternal(Element element) {
+ ImmutableList.Builder<String> flagsBuilder = ImmutableList.builder();
+ for (Element e : element.getChildren(tag)) {
+ String flag = e.getTextTrim();
+ if (flag != null && !flag.isEmpty()) {
+ flagsBuilder.add(flag);
+ }
+ }
+ flags = flagsBuilder.build();
+ }
+
+ @Override
+ public void writeExternal(Element element) {
+ element.removeChildren(tag);
+ for (String flag : flags) {
+ Element child = new Element(tag);
+ child.setText(flag);
+ element.addContent(child);
+ }
+ }
+
+ @Override
+ public RunConfigurationStateEditor getEditor(Project project) {
+ return new RunConfigurationFlagsStateEditor(fieldLabel);
+ }
+
+ private static class RunConfigurationFlagsStateEditor implements RunConfigurationStateEditor {
+
+ private final JTextArea flagsField = new JTextArea(5, 1);
+ private final String fieldLabel;
+
+ RunConfigurationFlagsStateEditor(String fieldLabel) {
+ this.fieldLabel = fieldLabel;
+ }
+
+ private static String makeFlagString(List<String> flags) {
+ StringBuilder flagString = new StringBuilder();
+ for (String flag : flags) {
+ if (flagString.length() > 0) {
+ flagString.append('\n');
+ }
+ if (flag.isEmpty() || flag.contains(" ") || flag.contains("|")) {
+ flagString.append('"');
+ flagString.append(flag);
+ flagString.append('"');
+ } else {
+ flagString.append(flag);
+ }
+ }
+ return flagString.toString();
+ }
+
+ @Override
+ public void resetEditorFrom(RunConfigurationState genericState) {
+ RunConfigurationFlagsState state = (RunConfigurationFlagsState) genericState;
+ // Normally we could just use ParametersListUtils.join, but that will only space-delimit args.
+ flagsField.setText(makeFlagString(state.getFlags()));
+ }
+
+ @Override
+ public void applyEditorTo(RunConfigurationState genericState) {
+ RunConfigurationFlagsState state = (RunConfigurationFlagsState) genericState;
+ state.setFlags(ParametersListUtil.parse(Strings.nullToEmpty(flagsField.getText())));
+ }
+
+ @Override
+ public JComponent createComponent() {
+ return UiUtil.createBox(
+ new JLabel(fieldLabel),
+ new JScrollPane(
+ flagsField,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED));
+ }
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/run/state/RunConfigurationState.java b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationState.java
new file mode 100644
index 0000000..8a01f01
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationState.java
@@ -0,0 +1,35 @@
+/*
+ * 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.run.state;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import org.jdom.Element;
+
+/** Supports managing part of a run configuration's state. */
+public interface RunConfigurationState {
+
+ /** Loads this handler's state from the external data. */
+ void readExternal(Element element) throws InvalidDataException;
+
+ /** Updates the element with the handler's state. */
+ @SuppressWarnings("ThrowsUncheckedException")
+ void writeExternal(Element element) throws WriteExternalException;
+
+ /** @return A {@link RunConfigurationStateEditor} for this state. */
+ RunConfigurationStateEditor getEditor(Project project);
+}
diff --git a/base/src/com/google/idea/blaze/base/run/state/RunConfigurationStateEditor.java b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationStateEditor.java
new file mode 100644
index 0000000..b04020e
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/run/state/RunConfigurationStateEditor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.run.state;
+
+import javax.swing.JComponent;
+
+/** Provides support for editing {@link RunConfigurationState}s. */
+public interface RunConfigurationStateEditor {
+
+ /** Reset the editor based on the given state. */
+ void resetEditorFrom(RunConfigurationState state);
+
+ /** Update the given state based on the editor. */
+ void applyEditorTo(RunConfigurationState state);
+
+ /** @return A component to display for the editor. */
+ JComponent createComponent();
+}
diff --git a/base/src/com/google/idea/blaze/base/run/testmap/TestRuleFinderImpl.java b/base/src/com/google/idea/blaze/base/run/testmap/TestRuleFinderImpl.java
index 258f059..9f51c32 100644
--- a/base/src/com/google/idea/blaze/base/run/testmap/TestRuleFinderImpl.java
+++ b/base/src/com/google/idea/blaze/base/run/testmap/TestRuleFinderImpl.java
@@ -25,15 +25,18 @@
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.TestRuleFinder;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.google.idea.blaze.base.sync.SyncListener;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.openapi.project.Project;
import java.io.File;
import java.util.Collection;
@@ -55,12 +58,12 @@
static class TestMap {
private final Project project;
- private final Multimap<File, Label> rootsMap;
+ private final Multimap<File, RuleKey> rootsMap;
private final RuleMap ruleMap;
- TestMap(Project project, RuleMap ruleMap) {
+ TestMap(Project project, ArtifactLocationDecoder artifactLocationDecoder, RuleMap ruleMap) {
this.project = project;
- this.rootsMap = createRootsMap(ruleMap.rules());
+ this.rootsMap = createRootsMap(artifactLocationDecoder, ruleMap.rules());
this.ruleMap = ruleMap;
}
@@ -75,45 +78,47 @@
@VisibleForTesting
Collection<Label> testTargetsForSourceFile(
- ImmutableMultimap<Label, Label> rdepsMap, File sourceFile) {
+ ImmutableMultimap<RuleKey, RuleKey> rdepsMap, File sourceFile) {
return testRulesForSourceFile(rdepsMap, sourceFile)
.stream()
- .map((rule) -> rule.label)
+ .filter(RuleIdeInfo::isPlainTarget)
+ .map(rule -> rule.label)
.collect(Collectors.toList());
}
Collection<RuleIdeInfo> testRulesForSourceFile(
- ImmutableMultimap<Label, Label> rdepsMap, File sourceFile) {
+ ImmutableMultimap<RuleKey, RuleKey> rdepsMap, File sourceFile) {
List<RuleIdeInfo> result = Lists.newArrayList();
- Collection<Label> roots = rootsMap.get(sourceFile);
+ Collection<RuleKey> roots = rootsMap.get(sourceFile);
- Queue<Label> todo = Queues.newArrayDeque();
- for (Label label : roots) {
+ Queue<RuleKey> todo = Queues.newArrayDeque();
+ for (RuleKey label : roots) {
todo.add(label);
}
- Set<Label> seen = Sets.newHashSet();
+ Set<RuleKey> seen = Sets.newHashSet();
while (!todo.isEmpty()) {
- Label label = todo.remove();
- if (!seen.add(label)) {
+ RuleKey ruleKey = todo.remove();
+ if (!seen.add(ruleKey)) {
continue;
}
- RuleIdeInfo rule = ruleMap.get(label);
+ RuleIdeInfo rule = ruleMap.get(ruleKey);
if (isTestRule(rule)) {
result.add(rule);
}
- for (Label rdep : rdepsMap.get(label)) {
+ for (RuleKey rdep : rdepsMap.get(ruleKey)) {
todo.add(rdep);
}
}
return result;
}
- static Multimap<File, Label> createRootsMap(Collection<RuleIdeInfo> rules) {
- Multimap<File, Label> result = ArrayListMultimap.create();
+ static Multimap<File, RuleKey> createRootsMap(
+ ArtifactLocationDecoder artifactLocationDecoder, Collection<RuleIdeInfo> rules) {
+ Multimap<File, RuleKey> result = ArrayListMultimap.create();
for (RuleIdeInfo ruleIdeInfo : rules) {
for (ArtifactLocation source : ruleIdeInfo.sources) {
- result.put(source.getFile(), ruleIdeInfo.label);
+ result.put(artifactLocationDecoder.decode(source), ruleIdeInfo.key);
}
}
return result;
@@ -158,7 +163,7 @@
if (blazeProjectData == null) {
return null;
}
- return new TestMap(project, blazeProjectData.ruleMap);
+ return new TestMap(project, blazeProjectData.artifactLocationDecoder, blazeProjectData.ruleMap);
}
private synchronized void clearMapData() {
@@ -169,6 +174,7 @@
@Override
public void onSyncComplete(
Project project,
+ BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
diff --git a/base/src/com/google/idea/blaze/base/sync/BlazeSyncPlugin.java b/base/src/com/google/idea/blaze/base/sync/BlazeSyncPlugin.java
index 985ff17..4c7d64e 100644
--- a/base/src/com/google/idea/blaze/base/sync/BlazeSyncPlugin.java
+++ b/base/src/com/google/idea/blaze/base/sync/BlazeSyncPlugin.java
@@ -17,8 +17,8 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
@@ -27,6 +27,7 @@
import com.google.idea.blaze.base.projectview.section.SectionParser;
import com.google.idea.blaze.base.scope.BlazeContext;
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;
@@ -99,6 +100,7 @@
BlazeRoots blazeRoots,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
+ ArtifactLocationDecoder artifactLocationDecoder,
RuleMap ruleMap,
SyncState.Builder syncStateBuilder,
@Nullable SyncState previousSyncState);
@@ -183,6 +185,7 @@
BlazeRoots blazeRoots,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
+ ArtifactLocationDecoder artifactLocationDecoder,
RuleMap ruleMap,
SyncState.Builder syncStateBuilder,
@Nullable SyncState previousSyncState) {}
diff --git a/base/src/com/google/idea/blaze/base/sync/BlazeSyncTask.java b/base/src/com/google/idea/blaze/base/sync/BlazeSyncTask.java
index a49b8bf..6b5c4dc 100755
--- a/base/src/com/google/idea/blaze/base/sync/BlazeSyncTask.java
+++ b/base/src/com/google/idea/blaze/base/sync/BlazeSyncTask.java
@@ -26,11 +26,11 @@
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.experiments.ExperimentScope;
import com.google.idea.blaze.base.filecache.FileCaches;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.metrics.Action;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
-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.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
@@ -69,6 +69,7 @@
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.ArtifactLocationDecoder;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoderImpl;
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;
@@ -149,13 +150,13 @@
SyncResult syncResult = SyncResult.FAILURE;
try {
SaveUtil.saveAllFiles();
- onSyncStart(project);
+ onSyncStart(project, context);
syncResult = doSyncProject(context);
} catch (AssertionError | Exception e) {
LOG.error(e);
IssueOutput.error("Internal error: " + e.getMessage()).submit(context);
} finally {
- afterSync(project, syncResult);
+ afterSync(project, context, syncResult);
}
return syncResult == SyncResult.SUCCESS || syncResult == SyncResult.PARTIAL_SUCCESS;
}
@@ -215,6 +216,8 @@
}
WorkspacePathResolver workspacePathResolver =
workspacePathResolverAndProjectView.workspacePathResolver;
+ ArtifactLocationDecoder artifactLocationDecoder =
+ new ArtifactLocationDecoderImpl(blazeRoots, workspacePathResolver);
ProjectViewSet projectViewSet = workspacePathResolverAndProjectView.projectViewSet;
WorkspaceLanguageSettings workspaceLanguageSettings =
@@ -277,7 +280,7 @@
projectViewSet,
targets,
workspaceLanguageSettings,
- new ArtifactLocationDecoder(blazeRoots, workspacePathResolver),
+ artifactLocationDecoder,
syncStateBuilder,
previousSyncState,
mergeWithOldState);
@@ -292,7 +295,7 @@
RuleMap ruleMap = ideQueryResult.ruleMap;
ideInfoResult = ideQueryResult.buildResult;
- ListenableFuture<ImmutableMultimap<Label, Label>> reverseDependenciesFuture =
+ ListenableFuture<ImmutableMultimap<RuleKey, RuleKey>> reverseDependenciesFuture =
BlazeExecutor.getInstance().submit(() -> ReverseDependencyMap.createRdepsMap(ruleMap));
boolean doResolve = syncPluginRequiresBuild || oldBlazeProjectData == null;
@@ -322,13 +325,14 @@
blazeRoots,
workingSet,
workspacePathResolver,
+ artifactLocationDecoder,
ruleMap,
syncStateBuilder,
previousSyncState);
}
});
- ImmutableMultimap<Label, Label> reverseDependencies =
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
FutureUtil.waitForFuture(context, reverseDependenciesFuture)
.timed("ReverseDependencies")
.onError("Failed to compute reverse dependency map")
@@ -345,6 +349,7 @@
blazeRoots,
workingSet,
workspacePathResolver,
+ artifactLocationDecoder,
workspaceLanguageSettings,
syncStateBuilder.build(),
reverseDependencies,
@@ -685,17 +690,17 @@
return VirtualFileManager.constructUrl(StandardFileSystems.FILE_PROTOCOL, filePath);
}
- private static void onSyncStart(Project project) {
+ private static void onSyncStart(Project project, BlazeContext context) {
final SyncListener[] syncListeners = SyncListener.EP_NAME.getExtensions();
for (SyncListener syncListener : syncListeners) {
- syncListener.onSyncStart(project);
+ syncListener.onSyncStart(project, context);
}
}
- private static void afterSync(Project project, SyncResult syncResult) {
+ private static void afterSync(Project project, BlazeContext context, SyncResult syncResult) {
final SyncListener[] syncListeners = SyncListener.EP_NAME.getExtensions();
for (SyncListener syncListener : syncListeners) {
- syncListener.afterSync(project, syncResult);
+ syncListener.afterSync(project, context, syncResult);
}
}
@@ -710,7 +715,7 @@
final SyncListener[] syncListeners = SyncListener.EP_NAME.getExtensions();
for (SyncListener syncListener : syncListeners) {
syncListener.onSyncComplete(
- project, importSettings, projectViewSet, blazeProjectData, syncResult);
+ project, context, importSettings, projectViewSet, blazeProjectData, syncResult);
}
}
diff --git a/base/src/com/google/idea/blaze/base/sync/SyncListener.java b/base/src/com/google/idea/blaze/base/sync/SyncListener.java
index 6445b14..28ba5fc 100644
--- a/base/src/com/google/idea/blaze/base/sync/SyncListener.java
+++ b/base/src/com/google/idea/blaze/base/sync/SyncListener.java
@@ -17,6 +17,7 @@
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.project.Project;
@@ -39,34 +40,36 @@
}
/** Called after open documents have been saved, prior to starting the blaze sync. */
- void onSyncStart(Project project);
+ void onSyncStart(Project project, BlazeContext context);
/** Called on successful (or partially successful) completion of a sync */
void onSyncComplete(
Project project,
+ BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
SyncResult syncResult);
/** Guaranteed to be called once per sync, regardless of whether it successfully completed */
- void afterSync(Project project, SyncResult syncResult);
+ void afterSync(Project project, BlazeContext context, SyncResult syncResult);
/** Convenience adapter class. */
abstract class Adapter implements SyncListener {
@Override
- public void onSyncStart(Project project) {}
+ public void onSyncStart(Project project, BlazeContext context) {}
@Override
public void onSyncComplete(
Project project,
+ BlazeContext context,
BlazeImportSettings importSettings,
ProjectViewSet projectViewSet,
BlazeProjectData blazeProjectData,
SyncResult syncResult) {}
@Override
- public void afterSync(Project project, SyncResult syncResult) {}
+ public void afterSync(Project project, BlazeContext context, SyncResult syncResult) {}
}
}
diff --git a/base/src/com/google/idea/blaze/base/sync/actions/PartialSyncAction.java b/base/src/com/google/idea/blaze/base/sync/actions/PartialSyncAction.java
index 2d6512b..cba67de 100644
--- a/base/src/com/google/idea/blaze/base/sync/actions/PartialSyncAction.java
+++ b/base/src/com/google/idea/blaze/base/sync/actions/PartialSyncAction.java
@@ -92,7 +92,7 @@
} else {
targets.addAll(
SourceToRuleMap.getInstance(project)
- .getTargetsForSourceFile(new File(virtualFile.getPath())));
+ .getTargetsToBuildForSourceFile(new File(virtualFile.getPath())));
// If empty, try to build parent package
if (targets.isEmpty()) {
diff --git a/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterface.java b/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterface.java
index d46ac4a..573c4b8 100644
--- a/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterface.java
+++ b/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterface.java
@@ -15,7 +15,7 @@
*/
package com.google.idea.blaze.base.sync.aspects;
-import com.google.idea.blaze.base.model.RuleMap;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
diff --git a/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java b/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java
index 1b4be0e..936268e 100644
--- a/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java
+++ b/base/src/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImpl.java
@@ -32,11 +32,11 @@
import com.google.idea.blaze.base.command.ExperimentalShowArtifactsLineProcessor;
import com.google.idea.blaze.base.filecache.FileDiffer;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.metrics.Action;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
-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.prefetch.PrefetchService;
@@ -75,10 +75,10 @@
new BoolExperiment("ide.info.keep.going", true);
static class State implements Serializable {
- private static final long serialVersionUID = 13L;
+ private static final long serialVersionUID = 14L;
RuleMap ruleMap;
ImmutableMap<File, Long> fileState = null;
- Map<File, Label> fileToLabel = Maps.newHashMap();
+ Map<File, RuleKey> fileToRuleMapKey = Maps.newHashMap();
WorkspaceLanguageSettings workspaceLanguageSettings;
String aspectStrategyName;
}
@@ -273,19 +273,19 @@
state.workspaceLanguageSettings = workspaceLanguageSettings;
state.aspectStrategyName = aspectStrategy.getName();
- Map<Label, RuleIdeInfo> ruleMap = Maps.newHashMap();
- Map<Label, RuleIdeInfo> updatedRules = Maps.newHashMap();
+ Map<RuleKey, RuleIdeInfo> ruleMap = Maps.newHashMap();
+ Map<RuleKey, RuleIdeInfo> updatedRules = Maps.newHashMap();
if (prevState != null) {
ruleMap.putAll(prevState.ruleMap.map());
- state.fileToLabel.putAll(prevState.fileToLabel);
+ state.fileToRuleMapKey.putAll(prevState.fileToRuleMapKey);
}
// Update removed unless we're merging with the old state
if (!mergeWithOldState) {
for (File removedFile : removedFiles) {
- Label label = state.fileToLabel.remove(removedFile);
- if (label != null) {
- ruleMap.remove(label);
+ RuleKey key = state.fileToRuleMapKey.remove(removedFile);
+ if (key != null) {
+ ruleMap.remove(key);
}
}
}
@@ -306,9 +306,7 @@
aspectStrategy.readAspectFile(file);
RuleIdeInfo ruleIdeInfo =
IdeInfoFromProtobuf.makeRuleIdeInfo(
- workspaceLanguageSettings,
- artifactLocationDecoder,
- ruleProto);
+ workspaceLanguageSettings, ruleProto);
return new RuleIdeInfoPair(file, ruleIdeInfo);
}));
}
@@ -319,11 +317,11 @@
for (RuleIdeInfoPair ruleIdeInfoOrSdkInfo : Futures.allAsList(futures).get()) {
if (ruleIdeInfoOrSdkInfo.ruleIdeInfo != null) {
File file = ruleIdeInfoOrSdkInfo.file;
- Label label = ruleIdeInfoOrSdkInfo.ruleIdeInfo.label;
+ RuleKey key = ruleIdeInfoOrSdkInfo.ruleIdeInfo.key;
RuleIdeInfo previousRule =
- updatedRules.putIfAbsent(label, ruleIdeInfoOrSdkInfo.ruleIdeInfo);
+ updatedRules.putIfAbsent(key, ruleIdeInfoOrSdkInfo.ruleIdeInfo);
if (previousRule == null) {
- state.fileToLabel.put(file, label);
+ state.fileToRuleMapKey.put(file, key);
} else {
duplicateRuleLabels++;
}
diff --git a/base/src/com/google/idea/blaze/base/sync/aspects/IdeInfoFromProtobuf.java b/base/src/com/google/idea/blaze/base/sync/aspects/IdeInfoFromProtobuf.java
index 4f1e622..812148b 100644
--- a/base/src/com/google/idea/blaze/base/sync/aspects/IdeInfoFromProtobuf.java
+++ b/base/src/com/google/idea/blaze/base/sync/aspects/IdeInfoFromProtobuf.java
@@ -33,7 +33,6 @@
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
-import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo;
import com.google.repackaged.protobuf.ProtocolStringList;
import java.util.Collection;
@@ -46,7 +45,6 @@
@Nullable
public static RuleIdeInfo makeRuleIdeInfo(
WorkspaceLanguageSettings workspaceLanguageSettings,
- ArtifactLocationDecoder decoder,
AndroidStudioIdeInfo.RuleIdeInfo message) {
Kind kind = getKind(message);
if (kind == null) {
@@ -57,7 +55,7 @@
}
Label label = new Label(message.getLabel());
- ArtifactLocation buildFile = getBuildFile(decoder, message);
+ ArtifactLocation buildFile = getBuildFile(message);
Collection<Label> dependencies = makeLabelListFromProtobuf(message.getDependenciesList());
Collection<Label> runtimeDeps = makeLabelListFromProtobuf(message.getRuntimeDepsList());
@@ -66,7 +64,7 @@
Collection<ArtifactLocation> sources = Lists.newArrayList();
CRuleIdeInfo cRuleIdeInfo = null;
if (message.hasCRuleIdeInfo()) {
- cRuleIdeInfo = makeCRuleIdeInfo(decoder, message.getCRuleIdeInfo());
+ cRuleIdeInfo = makeCRuleIdeInfo(message.getCRuleIdeInfo());
sources.addAll(cRuleIdeInfo.sources);
}
CToolchainIdeInfo cToolchainIdeInfo = null;
@@ -75,14 +73,14 @@
}
JavaRuleIdeInfo javaRuleIdeInfo = null;
if (message.hasJavaRuleIdeInfo()) {
- javaRuleIdeInfo = makeJavaRuleIdeInfo(decoder, message.getJavaRuleIdeInfo());
+ javaRuleIdeInfo = makeJavaRuleIdeInfo(message.getJavaRuleIdeInfo());
Collection<ArtifactLocation> javaSources =
- makeArtifactLocationList(decoder, message.getJavaRuleIdeInfo().getSourcesList());
+ makeArtifactLocationList(message.getJavaRuleIdeInfo().getSourcesList());
sources.addAll(javaSources);
}
AndroidRuleIdeInfo androidRuleIdeInfo = null;
if (message.hasAndroidRuleIdeInfo()) {
- androidRuleIdeInfo = makeAndroidRuleIdeInfo(decoder, message.getAndroidRuleIdeInfo());
+ androidRuleIdeInfo = makeAndroidRuleIdeInfo(message.getAndroidRuleIdeInfo());
}
TestIdeInfo testIdeInfo = null;
if (message.hasTestInfo()) {
@@ -91,7 +89,7 @@
ProtoLibraryLegacyInfo protoLibraryLegacyInfo = null;
if (message.hasProtoLibraryLegacyJavaIdeInfo()) {
protoLibraryLegacyInfo =
- makeProtoLibraryLegacyInfo(decoder, message.getProtoLibraryLegacyJavaIdeInfo());
+ makeProtoLibraryLegacyInfo(message.getProtoLibraryLegacyJavaIdeInfo());
}
JavaToolchainIdeInfo javaToolchainIdeInfo = null;
if (message.hasJavaToolchainIdeInfo()) {
@@ -116,18 +114,15 @@
}
@Nullable
- private static ArtifactLocation getBuildFile(
- ArtifactLocationDecoder decoder, AndroidStudioIdeInfo.RuleIdeInfo message) {
+ private static ArtifactLocation getBuildFile(AndroidStudioIdeInfo.RuleIdeInfo message) {
if (message.hasBuildFileArtifactLocation()) {
- return makeArtifactLocation(decoder, message.getBuildFileArtifactLocation());
+ return makeArtifactLocation(message.getBuildFileArtifactLocation());
}
return null;
}
- private static CRuleIdeInfo makeCRuleIdeInfo(
- ArtifactLocationDecoder decoder, AndroidStudioIdeInfo.CRuleIdeInfo cRuleIdeInfo) {
- List<ArtifactLocation> sources =
- makeArtifactLocationList(decoder, cRuleIdeInfo.getSourceList());
+ private static CRuleIdeInfo makeCRuleIdeInfo(AndroidStudioIdeInfo.CRuleIdeInfo cRuleIdeInfo) {
+ List<ArtifactLocation> sources = makeArtifactLocationList(cRuleIdeInfo.getSourceList());
List<ExecutionRootPath> transitiveIncludeDirectories =
makeExecutionRootPathList(cRuleIdeInfo.getTransitiveIncludeDirectoryList());
List<ExecutionRootPath> transitiveQuoteIncludeDirectories =
@@ -183,35 +178,31 @@
}
private static JavaRuleIdeInfo makeJavaRuleIdeInfo(
- ArtifactLocationDecoder decoder, AndroidStudioIdeInfo.JavaRuleIdeInfo javaRuleIdeInfo) {
+ AndroidStudioIdeInfo.JavaRuleIdeInfo javaRuleIdeInfo) {
return new JavaRuleIdeInfo(
- makeLibraryArtifactList(decoder, javaRuleIdeInfo.getJarsList()),
- makeLibraryArtifactList(decoder, javaRuleIdeInfo.getGeneratedJarsList()),
+ makeLibraryArtifactList(javaRuleIdeInfo.getJarsList()),
+ makeLibraryArtifactList(javaRuleIdeInfo.getGeneratedJarsList()),
javaRuleIdeInfo.hasFilteredGenJar()
- ? makeLibraryArtifact(decoder, javaRuleIdeInfo.getFilteredGenJar())
+ ? makeLibraryArtifact(javaRuleIdeInfo.getFilteredGenJar())
: null,
javaRuleIdeInfo.hasPackageManifest()
- ? makeArtifactLocation(decoder, javaRuleIdeInfo.getPackageManifest())
+ ? makeArtifactLocation(javaRuleIdeInfo.getPackageManifest())
: null,
- javaRuleIdeInfo.hasJdeps()
- ? makeArtifactLocation(decoder, javaRuleIdeInfo.getJdeps())
- : null);
+ javaRuleIdeInfo.hasJdeps() ? makeArtifactLocation(javaRuleIdeInfo.getJdeps()) : null);
}
private static AndroidRuleIdeInfo makeAndroidRuleIdeInfo(
- ArtifactLocationDecoder decoder, AndroidStudioIdeInfo.AndroidRuleIdeInfo androidRuleIdeInfo) {
+ AndroidStudioIdeInfo.AndroidRuleIdeInfo androidRuleIdeInfo) {
return new AndroidRuleIdeInfo(
- makeArtifactLocationList(decoder, androidRuleIdeInfo.getResourcesList()),
+ makeArtifactLocationList(androidRuleIdeInfo.getResourcesList()),
androidRuleIdeInfo.getJavaPackage(),
androidRuleIdeInfo.getGenerateResourceClass(),
androidRuleIdeInfo.hasManifest()
- ? makeArtifactLocation(decoder, androidRuleIdeInfo.getManifest())
+ ? makeArtifactLocation(androidRuleIdeInfo.getManifest())
: null,
- androidRuleIdeInfo.hasIdlJar()
- ? makeLibraryArtifact(decoder, androidRuleIdeInfo.getIdlJar())
- : null,
+ androidRuleIdeInfo.hasIdlJar() ? makeLibraryArtifact(androidRuleIdeInfo.getIdlJar()) : null,
androidRuleIdeInfo.hasResourceJar()
- ? makeLibraryArtifact(decoder, androidRuleIdeInfo.getResourceJar())
+ ? makeLibraryArtifact(androidRuleIdeInfo.getResourceJar())
: null,
androidRuleIdeInfo.getHasIdlSources(),
!Strings.isNullOrEmpty(androidRuleIdeInfo.getLegacyResources())
@@ -244,7 +235,6 @@
}
private static ProtoLibraryLegacyInfo makeProtoLibraryLegacyInfo(
- ArtifactLocationDecoder decoder,
AndroidStudioIdeInfo.ProtoLibraryLegacyJavaIdeInfo protoLibraryLegacyJavaIdeInfo) {
final ProtoLibraryLegacyInfo.ApiFlavor apiFlavor;
if (protoLibraryLegacyJavaIdeInfo.getApiVersion() == 1) {
@@ -267,9 +257,9 @@
}
return new ProtoLibraryLegacyInfo(
apiFlavor,
- makeLibraryArtifactList(decoder, protoLibraryLegacyJavaIdeInfo.getJars1List()),
- makeLibraryArtifactList(decoder, protoLibraryLegacyJavaIdeInfo.getJarsMutableList()),
- makeLibraryArtifactList(decoder, protoLibraryLegacyJavaIdeInfo.getJarsImmutableList()));
+ makeLibraryArtifactList(protoLibraryLegacyJavaIdeInfo.getJars1List()),
+ makeLibraryArtifactList(protoLibraryLegacyJavaIdeInfo.getJarsMutableList()),
+ makeLibraryArtifactList(protoLibraryLegacyJavaIdeInfo.getJarsImmutableList()));
}
private static JavaToolchainIdeInfo makeJavaToolchainIdeInfo(
@@ -279,10 +269,10 @@
}
private static Collection<LibraryArtifact> makeLibraryArtifactList(
- ArtifactLocationDecoder decoder, List<AndroidStudioIdeInfo.LibraryArtifact> jarsList) {
+ List<AndroidStudioIdeInfo.LibraryArtifact> jarsList) {
ImmutableList.Builder<LibraryArtifact> builder = ImmutableList.builder();
for (AndroidStudioIdeInfo.LibraryArtifact libraryArtifact : jarsList) {
- LibraryArtifact lib = makeLibraryArtifact(decoder, libraryArtifact);
+ LibraryArtifact lib = makeLibraryArtifact(libraryArtifact);
if (lib != null) {
builder.add(lib);
}
@@ -292,16 +282,16 @@
@Nullable
private static LibraryArtifact makeLibraryArtifact(
- ArtifactLocationDecoder decoder, AndroidStudioIdeInfo.LibraryArtifact libraryArtifact) {
+ AndroidStudioIdeInfo.LibraryArtifact libraryArtifact) {
ArtifactLocation classJar =
- libraryArtifact.hasJar() ? makeArtifactLocation(decoder, libraryArtifact.getJar()) : null;
+ libraryArtifact.hasJar() ? makeArtifactLocation(libraryArtifact.getJar()) : null;
ArtifactLocation iJar =
libraryArtifact.hasInterfaceJar()
- ? makeArtifactLocation(decoder, libraryArtifact.getInterfaceJar())
+ ? makeArtifactLocation(libraryArtifact.getInterfaceJar())
: null;
ArtifactLocation sourceJar =
libraryArtifact.hasSourceJar()
- ? makeArtifactLocation(decoder, libraryArtifact.getSourceJar())
+ ? makeArtifactLocation(libraryArtifact.getSourceJar())
: null;
if (iJar == null && classJar == null) {
// Failed to find ArtifactLocation file --
@@ -312,10 +302,10 @@
}
private static List<ArtifactLocation> makeArtifactLocationList(
- ArtifactLocationDecoder decoder, List<AndroidStudioIdeInfo.ArtifactLocation> sourcesList) {
+ List<AndroidStudioIdeInfo.ArtifactLocation> sourcesList) {
ImmutableList.Builder<ArtifactLocation> builder = ImmutableList.builder();
for (AndroidStudioIdeInfo.ArtifactLocation pbArtifactLocation : sourcesList) {
- ArtifactLocation loc = makeArtifactLocation(decoder, pbArtifactLocation);
+ ArtifactLocation loc = makeArtifactLocation(pbArtifactLocation);
if (loc != null) {
builder.add(loc);
}
@@ -325,11 +315,15 @@
@Nullable
private static ArtifactLocation makeArtifactLocation(
- ArtifactLocationDecoder decoder, AndroidStudioIdeInfo.ArtifactLocation pbArtifactLocation) {
+ AndroidStudioIdeInfo.ArtifactLocation pbArtifactLocation) {
if (pbArtifactLocation == null) {
return null;
}
- return decoder.decode(pbArtifactLocation);
+ return ArtifactLocation.builder()
+ .setRootExecutionPathFragment(pbArtifactLocation.getRootExecutionPathFragment())
+ .setRelativePath(pbArtifactLocation.getRelativePath())
+ .setIsSource(pbArtifactLocation.getIsSource())
+ .build();
}
private static Collection<Label> makeLabelListFromProtobuf(ProtocolStringList dependenciesList) {
diff --git a/base/src/com/google/idea/blaze/base/sync/status/BlazeSyncStatusListener.java b/base/src/com/google/idea/blaze/base/sync/status/BlazeSyncStatusListener.java
index 05ca578..e843332 100644
--- a/base/src/com/google/idea/blaze/base/sync/status/BlazeSyncStatusListener.java
+++ b/base/src/com/google/idea/blaze/base/sync/status/BlazeSyncStatusListener.java
@@ -15,6 +15,7 @@
*/
package com.google.idea.blaze.base.sync.status;
+import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.sync.SyncListener;
import com.intellij.openapi.project.Project;
@@ -25,12 +26,12 @@
public class BlazeSyncStatusListener extends SyncListener.Adapter {
@Override
- public void onSyncStart(Project project) {
+ public void onSyncStart(Project project, BlazeContext context) {
BlazeSyncStatusImpl.getImpl(project).syncStarted();
}
@Override
- public void afterSync(Project project, SyncResult syncResult) {
+ public void afterSync(Project project, BlazeContext context, SyncResult syncResult) {
BlazeSyncStatusImpl.getImpl(project).syncEnded(syncResult);
}
}
diff --git a/base/src/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoder.java b/base/src/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoder.java
index 13fce58..ccdeb54 100644
--- a/base/src/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoder.java
+++ b/base/src/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoder.java
@@ -16,72 +16,18 @@
package com.google.idea.blaze.base.sync.workspace;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
-import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo;
-import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.PackageManifestOuterClass;
import java.io.File;
-import javax.annotation.Nullable;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
/** Decodes android_studio_ide_info.proto ArtifactLocation file paths */
-public class ArtifactLocationDecoder {
+public interface ArtifactLocationDecoder extends Serializable {
- private final BlazeRoots blazeRoots;
- private final WorkspacePathResolver pathResolver;
+ File decode(ArtifactLocation artifactLocation);
- public ArtifactLocationDecoder(BlazeRoots blazeRoots, WorkspacePathResolver pathResolver) {
- this.blazeRoots = blazeRoots;
- this.pathResolver = pathResolver;
- }
-
- /**
- * Decodes the ArtifactLocation proto, locates the absolute artifact file path. Returns null if
- * the file can't be found (presumably because it was removed since the blaze build)
- */
- @Nullable
- public ArtifactLocation decode(AndroidStudioIdeInfo.ArtifactLocation loc) {
- return decode(
- loc.getRootExecutionPathFragment(),
- loc.getRelativePath(),
- loc.getIsSource());
- }
-
- /**
- * Decodes the ArtifactLocation proto, locates the absolute artifact file path. Returns null if
- * the file can't be found (presumably because it was removed since the blaze build)
- */
- @Nullable
- public ArtifactLocation decode(PackageManifestOuterClass.ArtifactLocation loc) {
- return decode(
- loc.getRootExecutionPathFragment(),
- loc.getRelativePath(),
- loc.getIsSource());
- }
-
- @Nullable
- private ArtifactLocation decode(
- String rootExecutionPathFragment, String relativePath, boolean isSource) {
- File root;
- if (isSource) {
- root = pathResolver.findPackageRoot(relativePath);
- } else {
- root = new File(blazeRoots.executionRoot, rootExecutionPathFragment);
- }
- if (root == null) {
- return null;
- }
- return ArtifactLocation.builder()
- .setRootPath(root.toString())
- .setRootExecutionPathFragment(rootExecutionPathFragment)
- .setRelativePath(relativePath)
- .setIsSource(isSource)
- .build();
- }
-
- @Deprecated
- private String deriveRootExecutionPathFragmentFromRoot(String rootPath) {
- String execRoot = blazeRoots.executionRoot.toString();
- if (rootPath.startsWith(execRoot)) {
- return rootPath.substring(execRoot.length());
- }
- return "";
+ default List<File> decodeAll(Collection<ArtifactLocation> artifactLocations) {
+ return artifactLocations.stream().map(this::decode).collect(Collectors.toList());
}
}
diff --git a/base/src/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderImpl.java b/base/src/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderImpl.java
new file mode 100644
index 0000000..f31cace
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderImpl.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.base.sync.workspace;
+
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import java.io.File;
+
+/** Decodes android_studio_ide_info.proto ArtifactLocation file paths */
+public class ArtifactLocationDecoderImpl implements ArtifactLocationDecoder {
+ private static final long serialVersionUID = 1L;
+
+ private final BlazeRoots blazeRoots;
+ private final WorkspacePathResolver pathResolver;
+
+ public ArtifactLocationDecoderImpl(BlazeRoots blazeRoots, WorkspacePathResolver pathResolver) {
+ this.blazeRoots = blazeRoots;
+ this.pathResolver = pathResolver;
+ }
+
+ @Override
+ public File decode(ArtifactLocation artifactLocation) {
+ if (artifactLocation.isSource) {
+ File root = pathResolver.findPackageRoot(artifactLocation.getRelativePath());
+ return new File(root, artifactLocation.getRelativePath());
+ } else {
+ return new File(blazeRoots.executionRoot, artifactLocation.getExecutionRootRelativePath());
+ }
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolver.java b/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolver.java
index d01975d..f7f8df3 100644
--- a/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolver.java
+++ b/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolver.java
@@ -28,16 +28,14 @@
*/
public interface WorkspacePathResolver extends Serializable {
/** Resolves a workspace path to an absolute file. */
- @Nullable
default File resolveToFile(WorkspacePath workspacepath) {
return resolveToFile(workspacepath.relativePath());
}
/** Resolves a workspace relative path to an absolute file. */
- @Nullable
default File resolveToFile(String workspaceRelativePath) {
File packageRoot = findPackageRoot(workspaceRelativePath);
- return packageRoot != null ? new File(packageRoot, workspaceRelativePath) : null;
+ return new File(packageRoot, workspaceRelativePath);
}
/**
@@ -47,7 +45,6 @@
ImmutableList<File> resolveToIncludeDirectories(ExecutionRootPath executionRootPath);
/** Finds the package root directory that a workspace relative path is in. */
- @Nullable
File findPackageRoot(String relativePath);
/**
diff --git a/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImpl.java b/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImpl.java
index 5721b91..0dc1c69 100644
--- a/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImpl.java
+++ b/base/src/com/google/idea/blaze/base/sync/workspace/WorkspacePathResolverImpl.java
@@ -51,7 +51,6 @@
}
@Override
- @Nullable
public File findPackageRoot(String relativePath) {
if (packagePaths.size() == 1) {
return packagePaths.get(0);
@@ -63,7 +62,9 @@
return pkg;
}
}
- return null;
+
+ // Return first in package path, even though it might not exist
+ return packagePaths.get(0);
}
@Nullable
diff --git a/base/src/com/google/idea/blaze/base/util/BlazeHelperBinaryUtil.java b/base/src/com/google/idea/blaze/base/util/BlazeHelperBinaryUtil.java
index d89004e..49fb501 100644
--- a/base/src/com/google/idea/blaze/base/util/BlazeHelperBinaryUtil.java
+++ b/base/src/com/google/idea/blaze/base/util/BlazeHelperBinaryUtil.java
@@ -58,6 +58,7 @@
try (InputStream inputStream = URLUtil.openResourceStream(url)) {
Files.copy(inputStream, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
file.setExecutable(true);
+ file.deleteOnExit();
cachedFiles.put(binaryName, file);
return file;
} catch (IOException e) {
diff --git a/base/src/com/google/idea/blaze/base/vcs/VcsWorkspacePathResolver.java b/base/src/com/google/idea/blaze/base/vcs/VcsWorkspacePathResolver.java
deleted file mode 100644
index 2b5516c..0000000
--- a/base/src/com/google/idea/blaze/base/vcs/VcsWorkspacePathResolver.java
+++ /dev/null
@@ -1,26 +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.vcs;
-
-import java.io.File;
-import javax.annotation.Nullable;
-
-/** Created by tomlu on 5/13/16. */
-public interface VcsWorkspacePathResolver {
-
- @Nullable
- File findPackageRoot(String relativePath);
-}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/ArgumentCompletionContributorTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/ArgumentCompletionContributorTest.java
index db6e935..8db9661 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/ArgumentCompletionContributorTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/ArgumentCompletionContributorTest.java
@@ -22,67 +22,80 @@
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.editor.Editor;
import com.intellij.testFramework.fixtures.CompletionAutoPopupTester;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for code completion of funcall arguments. */
+@RunWith(JUnit4.class)
public class ArgumentCompletionContributorTest extends BuildFileIntegrationTestCase {
private CompletionAutoPopupTester completionTester;
- public void doSetup() {
- super.doSetup();
+ @Before
+ public final void before() {
completionTester = new CompletionAutoPopupTester(testFixture);
}
+ /** Completion UI testing can't be run on the EDT. */
@Override
- protected boolean runInDispatchThread() {
+ protected boolean runTestsOnEdt() {
return false;
}
- @Override
- protected void invokeTestRunnable(Runnable runnable) throws Exception {
- completionTester.runWithAutoPopupEnabled(runnable);
- }
-
+ @Test
public void testIncompleteFuncall() {
- BuildFile file =
- createBuildFile(
- "BUILD", "def function(name, deps, srcs):", " # empty function", "function(d");
+ completionTester.runWithAutoPopupEnabled(
+ () -> {
+ BuildFile file =
+ createBuildFile(
+ "BUILD", "def function(name, deps, srcs):", " # empty function", "function(d");
- Editor editor = openFileInEditor(file.getVirtualFile());
- setCaretPosition(editor, 2, "function(n".length());
+ Editor editor = openFileInEditor(file.getVirtualFile());
+ setCaretPosition(editor, 2, "function(n".length());
- LookupElement[] completionItems = testFixture.completeBasic();
- assertThat(completionItems).isNull();
+ LookupElement[] completionItems = testFixture.completeBasic();
+ assertThat(completionItems).isNull();
- assertFileContents(
- file, "def function(name, deps, srcs):", " # empty function", "function(deps");
+ assertFileContents(
+ file, "def function(name, deps, srcs):", " # empty function", "function(deps");
+ });
}
+ @Test
public void testExistingKeywordArg() {
- BuildFile file =
- createBuildFile(
- "BUILD",
- "def function(name, deps, srcs):",
- " # empty function",
- "function(name = \"lib\")");
+ completionTester.runWithAutoPopupEnabled(
+ () -> {
+ BuildFile file =
+ createBuildFile(
+ "BUILD",
+ "def function(name, deps, srcs):",
+ " # empty function",
+ "function(name = \"lib\")");
- Editor editor = openFileInEditor(file.getVirtualFile());
- setCaretPosition(editor, 2, "function(".length());
+ Editor editor = openFileInEditor(file.getVirtualFile());
+ setCaretPosition(editor, 2, "function(".length());
- String[] completionItems = getCompletionItemsAsStrings();
- assertThat(completionItems).hasLength(4);
- assertThat(completionItems).asList().containsAllOf("name", "deps", "srcs", "function");
+ String[] completionItems = getCompletionItemsAsStrings();
+ assertThat(completionItems).hasLength(4);
+ assertThat(completionItems).asList().containsAllOf("name", "deps", "srcs", "function");
+ });
}
+ @Test
public void testNoArgumentCompletionInComment() {
- BuildFile file =
- createBuildFile(
- "BUILD", "def function(name, deps, srcs):", " # empty function", "function(#");
+ completionTester.runWithAutoPopupEnabled(
+ () -> {
+ BuildFile file =
+ createBuildFile(
+ "BUILD", "def function(name, deps, srcs):", " # empty function", "function(#");
- Editor editor = openFileInEditor(file.getVirtualFile());
- setCaretPosition(editor, 2, "function(#".length());
+ Editor editor = openFileInEditor(file.getVirtualFile());
+ setCaretPosition(editor, 2, "function(#".length());
- completionTester.typeWithPauses("n");
- assertNull(testFixture.getLookup());
+ completionTester.typeWithPauses("n");
+ assertThat(testFixture.getLookup()).isNull();
+ });
}
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionAttributeCompletionContributorTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionAttributeCompletionContributorTest.java
index 6fe0d21..dba6e54 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionAttributeCompletionContributorTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionAttributeCompletionContributorTest.java
@@ -29,20 +29,25 @@
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for BuiltInFunctionAttributeCompletionContributor. */
+@RunWith(JUnit4.class)
public class BuiltInFunctionAttributeCompletionContributorTest
extends BuildFileIntegrationTestCase {
private MockBuildLanguageSpecProvider specProvider;
- @Override
- protected void doSetup() {
- super.doSetup();
+ @Before
+ public final void before() {
specProvider = new MockBuildLanguageSpecProvider();
registerApplicationService(BuildLanguageSpecProvider.class, specProvider);
}
+ @Test
public void testSimpleCompletion() {
setRuleAndAttributes("sh_binary", "name", "deps", "srcs", "data");
@@ -55,6 +60,7 @@
assertThat(completionItems).asList().containsAllOf("name", "deps", "srcs", "data");
}
+ @Test
public void testSimpleSingleCompletion() {
setRuleAndAttributes("sh_binary", "name", "deps", "srcs", "data");
@@ -68,6 +74,7 @@
assertFileContents(file, "sh_binary(", " name");
}
+ @Test
public void testNoCompletionInUnknownRule() {
setRuleAndAttributes("sh_binary", "name", "deps", "srcs", "data");
@@ -80,6 +87,7 @@
assertThat(completionItems).isEmpty();
}
+ @Test
public void testNoCompletionInComment() {
setRuleAndAttributes("sh_binary", "name", "deps", "srcs", "data");
@@ -87,9 +95,10 @@
Editor editor = openFileInEditor(file.getVirtualFile());
setCaretPosition(editor, 0, "sh_binary(#".length());
- assertEmpty(getCompletionItemsAsStrings());
+ assertThat(getCompletionItemsAsStrings()).isEmpty();
}
+ @Test
public void testCompletionInSkylarkExtension() {
setRuleAndAttributes("sh_binary", "name", "deps", "srcs", "data");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionCompletionContributorTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionCompletionContributorTest.java
index f448b7a..eb36aa4 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionCompletionContributorTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/BuiltInFunctionCompletionContributorTest.java
@@ -27,19 +27,24 @@
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests BuiltInFunctionCompletionContributor */
+@RunWith(JUnit4.class)
public class BuiltInFunctionCompletionContributorTest extends BuildFileIntegrationTestCase {
private MockBuildLanguageSpecProvider specProvider;
- @Override
- protected void doSetup() {
- super.doSetup();
+ @Before
+ public final void before() {
specProvider = new MockBuildLanguageSpecProvider();
registerApplicationService(BuildLanguageSpecProvider.class, specProvider);
}
+ @Test
public void testSimpleTopLevelCompletion() {
setRules("java_library", "android_binary");
@@ -56,6 +61,7 @@
assertFileContents(file, "");
}
+ @Test
public void testUniqueTopLevelCompletion() {
setRules("java_library", "android_binary");
@@ -71,6 +77,7 @@
assertCaretPosition(editor, 0, "java_library(".length());
}
+ @Test
public void testSkylarkNativeCompletion() {
setRules("java_library", "android_binary");
@@ -86,6 +93,7 @@
assertCaretPosition(editor, 1, " native.java_library(".length());
}
+ @Test
public void testNoCompletionInsideRule() {
setRules("java_library", "android_binary");
@@ -101,6 +109,7 @@
assertFileContents(file, contents);
}
+ @Test
public void testNoCompletionInComment() {
setRules("java_library", "android_binary");
@@ -109,7 +118,7 @@
Editor editor = openFileInEditor(file.getVirtualFile());
setCaretPosition(editor, 0, "#java".length());
- assertEmpty(getCompletionItemsAsStrings());
+ assertThat(getCompletionItemsAsStrings()).isEmpty();
}
private void setRules(String... ruleNames) {
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/FilePathCompletionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/FilePathCompletionTest.java
index 5838f8f..a6024e5 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/FilePathCompletionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/FilePathCompletionTest.java
@@ -21,10 +21,15 @@
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.vfs.VirtualFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests file path code completion in BUILD file labels. */
+@RunWith(JUnit4.class)
public class FilePathCompletionTest extends BuildFileIntegrationTestCase {
+ @Test
public void testUniqueDirectoryCompleted() {
BuildFile file = createBuildFile("java/BUILD", "'//'");
@@ -37,6 +42,7 @@
assertCaretPosition(editor, 0, "'//java".length());
}
+ @Test
public void testUniqueMultiSegmentDirectoryCompleted() {
BuildFile file = createBuildFile("java/com/google/BUILD", "'//'");
@@ -50,6 +56,7 @@
// expected to be a typical workflow -- complete a segment,
// get the possibilities, then start typing
// next segment and complete again
+ @Test
public void testMultiStageCompletion() {
createDirectory("foo");
createDirectory("bar");
@@ -77,6 +84,7 @@
assertCaretPosition(editor, 0, "'//other/foo".length());
}
+ @Test
public void testCompletionSuggestionString() {
createDirectory("foo");
createDirectory("bar");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/LocalSymbolCompletionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/LocalSymbolCompletionTest.java
index aab1659..1381c31 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/LocalSymbolCompletionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/LocalSymbolCompletionTest.java
@@ -20,8 +20,12 @@
import com.google.common.base.Joiner;
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.intellij.psi.PsiFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests code completion works with general symbols in scope. */
+@RunWith(JUnit4.class)
public class LocalSymbolCompletionTest extends BuildFileIntegrationTestCase {
private PsiFile setInput(String... fileContents) {
@@ -29,10 +33,11 @@
}
private void assertResult(String... resultingFileContents) {
- String s = testFixture.getFile().getText();
+ testFixture.getFile().getText();
testFixture.checkResult(Joiner.on("\n").join(resultingFileContents));
}
+ @Test
public void testLocalVariable() {
setInput("var = [a, b]", "def function(name, deps, srcs):", " v<caret>");
@@ -41,6 +46,7 @@
assertResult("var = [a, b]", "def function(name, deps, srcs):", " var<caret>");
}
+ @Test
public void testLocalFunction() {
setInput("def fnName():return True", "def function(name, deps, srcs):", " fnN<caret>");
@@ -49,6 +55,7 @@
assertResult("def fnName():return True", "def function(name, deps, srcs):", " fnName<caret>");
}
+ @Test
public void testNoCompletionAfterDot() {
setInput("var = [a, b]", "def function(name, deps, srcs):", " ext.v<caret>");
@@ -56,6 +63,7 @@
assertThat(completionItems).isEmpty();
}
+ @Test
public void testFunctionParam() {
setInput("def test(var):", " v<caret>");
@@ -66,6 +74,7 @@
// b/28912523: when symbol is present in multiple assignment statements, should only be
// included once in the code-completion dialog
+ @Test
public void testSymbolAssignedMultipleTimes() {
setInput("var = 1", "var = 2", "var = 3", "<caret>");
@@ -74,18 +83,21 @@
assertResult("var = 1", "var = 2", "var = 3", "var<caret>");
}
+ @Test
public void testSymbolDefinedOutsideScope() {
setInput("<caret>", "var = 1");
assertThat(getCompletionItemsAsStrings()).isEmpty();
}
+ @Test
public void testSymbolDefinedOutsideScope2() {
setInput("def fn():", " var = 1", "v<caret>");
assertThat(testFixture.completeBasic()).isEmpty();
}
+ @Test
public void testSymbolDefinedOutsideScope3() {
setInput("for var in (1, 2, 3): print var", "v<caret>");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/ParameterCompletionContributorTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/ParameterCompletionContributorTest.java
index afc25d0..4989580 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/ParameterCompletionContributorTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/ParameterCompletionContributorTest.java
@@ -21,10 +21,15 @@
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.editor.Editor;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests ParameterCompletionContributor. */
+@RunWith(JUnit4.class)
public class ParameterCompletionContributorTest extends BuildFileIntegrationTestCase {
+ @Test
public void testArgsCompletion() {
BuildFile file = createBuildFile("BUILD", "def function(arg1, *");
@@ -37,6 +42,7 @@
assertFileContents(file, "def function(arg1, *args");
}
+ @Test
public void testKwargsCompletion() {
BuildFile file = createBuildFile("BUILD", "def function(arg1, **");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/RuleTargetCompletionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/RuleTargetCompletionTest.java
index 6a289f7..2df632e 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/RuleTargetCompletionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/RuleTargetCompletionTest.java
@@ -21,10 +21,15 @@
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.editor.Editor;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests code completion of rule target labels. */
+@RunWith(JUnit4.class)
public class RuleTargetCompletionTest extends BuildFileIntegrationTestCase {
+ @Test
public void testLocalTarget() {
BuildFile file =
createBuildFile(
@@ -42,6 +47,7 @@
assertThat(completionItems[0].toString()).isEqualTo("':lib'");
}
+ @Test
public void testIgnoreContainingTarget() {
BuildFile file =
createBuildFile(
@@ -54,6 +60,7 @@
assertThat(completionItems).isEmpty();
}
+ @Test
public void testNotCodeCompletionInNameField() {
BuildFile file =
createBuildFile(
@@ -70,8 +77,9 @@
assertThat(completionItems).isEmpty();
}
+ @Test
public void testNonLocalTarget() {
- BuildFile foo = createBuildFile("java/com/google/foo/BUILD", "java_library(name = 'foo_lib')");
+ createBuildFile("java/com/google/foo/BUILD", "java_library(name = 'foo_lib')");
BuildFile bar =
createBuildFile(
@@ -87,8 +95,9 @@
assertThat(completionItems).asList().containsExactly("'//java/com/google/foo:foo_lib'");
}
+ @Test
public void testNonLocalRulesNotCompletedWithoutColon() {
- BuildFile foo = createBuildFile("java/com/google/foo/BUILD", "java_library(name = 'foo_lib')");
+ createBuildFile("java/com/google/foo/BUILD", "java_library(name = 'foo_lib')");
BuildFile bar =
createBuildFile(
@@ -104,6 +113,7 @@
assertThat(completionItems).isEmpty();
}
+ @Test
public void testPackageLocalRulesCompletedWithoutColon() {
BuildFile file =
createBuildFile(
@@ -125,8 +135,9 @@
" deps = ['lib']");
}
+ @Test
public void testLocalPathIgnoredForNonLocalLabels() {
- BuildFile rootPackage = createBuildFile("java/BUILD", "java_library(name = 'root_rule')");
+ createBuildFile("java/BUILD", "java_library(name = 'root_rule')");
BuildFile otherPackage =
createBuildFile(
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionCompletionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionCompletionTest.java
index 9038c9b..f402723 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionCompletionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionCompletionTest.java
@@ -19,8 +19,12 @@
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.intellij.openapi.vfs.VirtualFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests auto-complete of skylark bzl files in 'load' statements. */
+@RunWith(JUnit4.class)
public class SkylarkExtensionCompletionTest extends BuildFileIntegrationTestCase {
private VirtualFile createAndSetCaret(String filePath, String... fileContents) {
@@ -29,6 +33,7 @@
return file;
}
+ @Test
public void testSimpleCase() {
createFile("skylark.bzl");
VirtualFile file = createAndSetCaret("BUILD", "load(':<caret>'");
@@ -37,13 +42,15 @@
assertFileContents(file, "load(':skylark.bzl'");
}
+ @Test
public void testSelfNotInResults() {
createFile("BUILD");
- VirtualFile file = createAndSetCaret("self.bzl", "load(':<caret>'");
+ createAndSetCaret("self.bzl", "load(':<caret>'");
assertThat(testFixture.completeBasic()).isEmpty();
}
+ @Test
public void testSelfNotInResults2() {
createFile("skylark.bzl");
createFile("BUILD");
@@ -53,6 +60,7 @@
assertFileContents(file, "load(':skylark.bzl'");
}
+ @Test
public void testNoRulesInResults() {
createFile("java/com/google/foo/skylark.bzl");
createFile("java/com/google/foo/BUILD", "java_library(name = 'foo')");
@@ -69,15 +77,16 @@
assertFileContents(file, "'//java/com/google/foo:foo'");
}
+ @Test
public void testNonSkylarkFilesNotInResults() {
createFile("java/com/google/foo/text.txt");
- VirtualFile file =
- createAndSetCaret("java/com/google/bar/BUILD", "load('//java/com/google/foo:<caret>'");
+ createAndSetCaret("java/com/google/bar/BUILD", "load('//java/com/google/foo:<caret>'");
assertThat(testFixture.completeBasic()).isEmpty();
}
+ @Test
public void testLabelStartsWithColon() {
createFile("java/com/google/skylark.bzl");
VirtualFile file = createAndSetCaret("java/com/google/BUILD", "load(':<caret>'");
@@ -86,6 +95,7 @@
assertFileContents(file, "load(':skylark.bzl'");
}
+ @Test
public void testLabelStartsWithSlashes() {
createFile("java/com/google/skylark.bzl");
VirtualFile file =
@@ -95,6 +105,7 @@
assertFileContents(file, "load('//java/com/google:skylark.bzl'");
}
+ @Test
public void testLabelStartsWithSlashesWithoutColon() {
createFile("java/com/google/skylark.bzl");
VirtualFile file =
@@ -104,6 +115,7 @@
assertFileContents(file, "load('//java/com/google:skylark.bzl'");
}
+ @Test
public void testDirectoryCompletionInLoadStatement() {
createFile("java/com/google/skylark.bzl");
VirtualFile file = createAndSetCaret("java/com/google/BUILD", "load('//<caret>'");
@@ -115,11 +127,11 @@
assertFileContents(file, "load('//java/com/google:skylark.bzl'");
}
+ @Test
public void testMultipleFiles() {
createFile("java/com/google/skylark.bzl");
createFile("java/com/google/other.bzl");
- VirtualFile file =
- createAndSetCaret("java/com/google/BUILD", "load('//java/com/google:<caret>'");
+ createAndSetCaret("java/com/google/BUILD", "load('//java/com/google:<caret>'");
String[] strings = getCompletionItemsAsStrings();
assertThat(strings).hasLength(2);
@@ -130,6 +142,7 @@
// relative paths in skylark extensions which lie in subdirectories
// are relative to the parent blaze package directory
+ @Test
public void testRelativePathInSubdirectory() {
createFile("java/com/google/BUILD");
createFile("java/com/google/nonPackageSubdirectory/skylark.bzl", "def function(): return");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionSymbolCompletionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionSymbolCompletionTest.java
index 4c00b51..4f85d97 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionSymbolCompletionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/completion/SkylarkExtensionSymbolCompletionTest.java
@@ -19,8 +19,12 @@
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.intellij.openapi.vfs.VirtualFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests auto-complete of symbols loaded from skylark bzl files. */
+@RunWith(JUnit4.class)
public class SkylarkExtensionSymbolCompletionTest extends BuildFileIntegrationTestCase {
private VirtualFile createAndSetCaret(String filePath, String... fileContents) {
@@ -29,6 +33,7 @@
return file;
}
+ @Test
public void testGlobalVariable() {
createFile("skylark.bzl", "VAR = []");
VirtualFile file = createAndSetCaret("BUILD", "load(':skylark.bzl', '<caret>')");
@@ -37,6 +42,7 @@
assertFileContents(file, "load(':skylark.bzl', 'VAR')");
}
+ @Test
public void testFunctionStatement() {
createFile("skylark.bzl", "def fn(param):stmt");
VirtualFile file = createAndSetCaret("BUILD", "load(':skylark.bzl', '<caret>')");
@@ -45,22 +51,24 @@
assertFileContents(file, "load(':skylark.bzl', 'fn')");
}
+ @Test
public void testMultipleOptions() {
createFile("skylark.bzl", "def fn(param):stmt", "VAR = []");
- VirtualFile file = createAndSetCaret("BUILD", "load(':skylark.bzl', '<caret>')");
+ createAndSetCaret("BUILD", "load(':skylark.bzl', '<caret>')");
String[] options = getCompletionItemsAsStrings();
assertThat(options).asList().containsExactly("'fn'", "'VAR'");
}
+ @Test
public void testRulesNotIncluded() {
createFile("skylark.bzl", "java_library(name = 'lib')", "native.java_library(name = 'foo'");
-
- VirtualFile file = createAndSetCaret("BUILD", "load(':skylark.bzl', '<caret>')");
+ createAndSetCaret("BUILD", "load(':skylark.bzl', '<caret>')");
assertThat(testFixture.completeBasic()).isEmpty();
}
+ @Test
public void testLoadedSymbols() {
createFile("other.bzl", "def function()");
createFile("skylark.bzl", "load(':other.bzl', 'function')");
@@ -70,6 +78,7 @@
assertFileContents(file, "load(':skylark.bzl', 'function')");
}
+ @Test
public void testNotLoadedSymbolsAreNotIncluded() {
createFile("other.bzl", "def function():stmt", "def other_function():stmt");
createFile("skylark.bzl", "load(':other.bzl', 'function')");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildBraceMatcherTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildBraceMatcherTest.java
index ac3b331..c4af1d4 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildBraceMatcherTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildBraceMatcherTest.java
@@ -18,14 +18,19 @@
import com.google.common.base.Joiner;
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.intellij.psi.PsiFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Test brace matching (auto-inserting closing braces when appropriate) */
+@RunWith(JUnit4.class)
public class BuildBraceMatcherTest extends BuildFileIntegrationTestCase {
private PsiFile setInput(String... fileContents) {
return testFixture.configureByText("BUILD", Joiner.on("\n").join(fileContents));
}
+ @Test
public void testClosingParenInserted() {
PsiFile file = setInput("java_library<caret>");
@@ -34,6 +39,7 @@
assertFileContents(file, "java_library()");
}
+ @Test
public void testClosingBraceInserted() {
PsiFile file = setInput("<caret>");
@@ -42,6 +48,7 @@
assertFileContents(file, "{}");
}
+ @Test
public void testClosingBracketInserted() {
PsiFile file = setInput("<caret>");
@@ -50,6 +57,7 @@
assertFileContents(file, "[]");
}
+ @Test
public void testNoClosingBracketInsertedIfLaterDanglingRBracket() {
PsiFile file = setInput("java_library(", " srcs =<caret> 'source.java']", ")");
@@ -58,6 +66,7 @@
assertFileContents(file, "java_library(", " srcs =[ 'source.java']", ")");
}
+ @Test
public void testClosingBracketInsertedIfFollowedByWhitespace() {
PsiFile file = setInput("java_library(", " srcs =<caret> 'source.java'", ")");
@@ -66,6 +75,7 @@
assertFileContents(file, "java_library(", " srcs =[] 'source.java'", ")");
}
+ @Test
public void testNoClosingBraceInsertedWhenFollowedByIdentifier() {
PsiFile file = setInput("hello = <caret>test");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildIndentOnEnterTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildIndentOnEnterTest.java
index eaccda5..684255a 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildIndentOnEnterTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildIndentOnEnterTest.java
@@ -18,8 +18,12 @@
import com.google.common.base.Joiner;
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.intellij.openapi.actionSystem.IdeActions;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that indents are inserted correctly when enter is pressed. */
+@RunWith(JUnit4.class)
public class BuildIndentOnEnterTest extends BuildFileIntegrationTestCase {
private void setInput(String... fileContents) {
@@ -28,197 +32,235 @@
private void pressEnterAndAssertResult(String... resultingFileContents) {
pressButton(IdeActions.ACTION_EDITOR_ENTER);
- String s = testFixture.getFile().getText();
+ testFixture.getFile().getText();
testFixture.checkResult(Joiner.on("\n").join(resultingFileContents));
}
+ @Test
public void testSimpleIndent() {
setInput("a=1<caret>");
pressEnterAndAssertResult("a=1", "<caret>");
}
+ @Test
public void testAlignInListMiddle() {
setInput("target = [a,<caret>", " c]");
pressEnterAndAssertResult("target = [a,", " <caret>", " c]");
}
+ @Test
public void testNoAlignAfterList() {
setInput("target = [", " arg", "]<caret>");
pressEnterAndAssertResult("target = [", " arg", "]", "<caret>");
}
+ @Test
public void testAlignInDict() {
setInput("some_call({'aaa': 'v1',<caret>})");
pressEnterAndAssertResult("some_call({'aaa': 'v1',", " <caret>})");
}
+ @Test
public void testAlignInDictInParams() { // PY-1947
setInput("foobar({<caret>})");
pressEnterAndAssertResult("foobar({", " <caret>", "})");
}
+ @Test
public void testAlignInEmptyList() {
setInput("target = [<caret>]");
pressEnterAndAssertResult("target = [", " <caret>", "]");
}
+ @Test
public void testAlignInEmptyParens() {
setInput("foo(<caret>)");
pressEnterAndAssertResult("foo(", " <caret>", ")");
}
+ @Test
public void testAlignInEmptyDict() {
setInput("{<caret>}");
pressEnterAndAssertResult("{", " <caret>", "}");
}
+ @Test
public void testAlignInEmptyTuple() {
setInput("(<caret>)");
pressEnterAndAssertResult("(", " <caret>", ")");
}
+ @Test
public void testEnterInNonEmptyArgList() {
setInput("func(<caret>params=1)");
pressEnterAndAssertResult("func(", " <caret>params=1)");
}
+ @Test
public void testNoIndentAfterTuple() {
setInput("()<caret>");
pressEnterAndAssertResult("()", "<caret>");
}
+ @Test
public void testNoIndentAfterList() {
setInput("target = [1, 2]<caret>");
pressEnterAndAssertResult("target = [1, 2]", "<caret>");
}
+ @Test
public void testNoIndentAfterDict() {
setInput("target = {}<caret>");
pressEnterAndAssertResult("target = {}", "<caret>");
}
+ @Test
public void testEmptyFuncallStart() {
setInput("func(<caret>", ")");
pressEnterAndAssertResult("func(", " <caret>", ")");
}
+ @Test
public void testEmptyFuncallAfterNewlineNoIndent() {
setInput("func(", "<caret>)");
pressEnterAndAssertResult("func(", "", "<caret>)");
}
+ @Test
public void testEmptyFuncallAfterNewlineWithIndent() {
setInput("func(", " <caret>", ")");
pressEnterAndAssertResult("func(", " ", " <caret>", ")");
}
+ @Test
public void testFuncallAfterFirstArg() {
setInput("func(", " arg1,<caret>", ")");
pressEnterAndAssertResult("func(", " arg1,", " <caret>", ")");
}
+ @Test
public void testFuncallFirstArgOnSameLine() {
setInput("func(arg1, arg2,<caret>");
pressEnterAndAssertResult("func(arg1, arg2,", " <caret>");
}
+ @Test
public void testFuncallFirstArgOnSameLineWithClosingBrace() {
setInput("func(arg1, arg2,<caret>)");
pressEnterAndAssertResult("func(arg1, arg2,", " <caret>)");
}
+ @Test
public void testNonEmptyDict() {
setInput("{key1 : value1,<caret>}");
pressEnterAndAssertResult("{key1 : value1,", " <caret>}");
}
+ @Test
public void testNonEmptyDictFirstArgIndented() {
setInput("{", " key1 : value1,<caret>" + "}");
pressEnterAndAssertResult("{", " key1 : value1,", " <caret>" + "}");
}
+ @Test
public void testEmptyDictAlreadyIndented() {
setInput("{", " <caret>" + "}");
pressEnterAndAssertResult("{", " ", " <caret>" + "}");
}
+ @Test
public void testEmptyParamIndent() {
setInput("def fn(<caret>)");
pressEnterAndAssertResult("def fn(", " <caret>", ")");
}
+ @Test
public void testNonEmptyParamIndent() {
setInput("def fn(param1,<caret>)");
pressEnterAndAssertResult("def fn(param1,", " <caret>)");
}
+ @Test
public void testFunctionDefAfterColon() {
setInput("def fn():<caret>");
pressEnterAndAssertResult("def fn():", " <caret>");
}
// def fn():stmt* (THIS IS CURRENTLY BROKEN -- shouldn't indent but does)
+ @Test
public void testFunctionDefSingleStatement() {
setInput("def fn():stmt<caret>");
pressEnterAndAssertResult("def fn():stmt", "<caret>");
}
+ @Test
public void testFunctionDefAfterFirstSuiteStatement() {
setInput("def fn():", " stmt1<caret>");
pressEnterAndAssertResult("def fn():", " stmt1", " <caret>");
}
+ @Test
public void testNoIndentAfterSuiteDedentOnEmptyLine() {
setInput("def fn():", " stmt1", " stmt2", "<caret>");
pressEnterAndAssertResult("def fn():", " stmt1", " stmt2", "", "<caret>");
}
+ @Test
public void testIndentAfterIf() {
setInput("if condition:<caret>");
pressEnterAndAssertResult("if condition:", " <caret>");
}
+ @Test
public void testNoIndentAfterIfPlusStatement() {
setInput("if condition:stmt<caret>");
pressEnterAndAssertResult("if condition:stmt", "<caret>");
}
+ @Test
public void testIndentAfterElseIf() {
setInput("if condition:", " stmt", "elif:<caret>");
pressEnterAndAssertResult("if condition:", " stmt", "elif:", " <caret>");
}
+ @Test
public void testNoIndentAfterElseIfPlusStatement() {
setInput("if condition:", " stmt", "elif:stmt<caret>");
pressEnterAndAssertResult("if condition:", " stmt", "elif:stmt", "<caret>");
}
+ @Test
public void testIndentAfterElse() {
setInput("if condition:", " stmt", "else:<caret>");
pressEnterAndAssertResult("if condition:", " stmt", "else:", " <caret>");
}
+ @Test
public void testNoIndentAfterElsePlusStatement() {
setInput("if condition:", " stmt", "else:stmt<caret>");
pressEnterAndAssertResult("if condition:", " stmt", "else:stmt", "<caret>");
}
+ @Test
public void testIndentAfterForColon() {
setInput("for x in list:<caret>");
pressEnterAndAssertResult("for x in list:", " <caret>");
}
+ @Test
public void testNoIndentAfterForPlusStatement() {
setInput("for x in list:do_action<caret>");
pressEnterAndAssertResult("for x in list:do_action", "<caret>");
}
+ @Test
public void testCommonRuleCase1() {
setInput("java_library(", " name = 'lib'", " srcs = [<caret>]");
pressEnterAndAssertResult(
"java_library(", " name = 'lib'", " srcs = [", " <caret>", " ]");
}
+ @Test
public void testCommonRuleCase2() {
setInput(
"java_library(", " name = 'lib'", " srcs = [", " 'source',<caret>", " ]");
@@ -231,43 +273,51 @@
" ]");
}
+ @Test
public void testCommonRuleCase3() {
setInput("java_library(", " name = 'lib'", " srcs = ['first',<caret>]");
pressEnterAndAssertResult(
"java_library(", " name = 'lib'", " srcs = ['first',", " <caret>]");
}
+ @Test
public void testDedentAfterReturn() {
setInput("def fn():", " return None<caret>");
pressEnterAndAssertResult("def fn():", " return None", "<caret>");
}
+ @Test
public void testDedentAfterEmptyReturn() {
setInput("def fn():", " return<caret>");
pressEnterAndAssertResult("def fn():", " return", "<caret>");
}
+ @Test
public void testDedentAfterReturnWithTrailingWhitespace() {
setInput("def fn():", " return<caret> ");
pressEnterAndAssertResult("def fn():", " return", "<caret>");
}
+ @Test
public void testDedentAfterComplexReturn() {
setInput("def fn():", " return a == b<caret>");
pressEnterAndAssertResult("def fn():", " return a == b", "<caret>");
}
+ @Test
public void testDedentAfterPass() {
setInput("def fn():", " pass<caret>");
pressEnterAndAssertResult("def fn():", " pass", "<caret>");
}
+ @Test
public void testDedentAfterPassInLoop() {
setInput("def fn():", " for a in (1,2,3):", " pass<caret>");
pressEnterAndAssertResult("def fn():", " for a in (1,2,3):", " pass", " <caret>");
}
// regression test for b/29564041
+ @Test
public void testNoExceptionPressingEnterAtStartOfFile() {
setInput("#<caret>");
pressEnterAndAssertResult("#", "<caret>");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildQuoteHandlerTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildQuoteHandlerTest.java
index 459d942..693ea1b 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildQuoteHandlerTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/BuildQuoteHandlerTest.java
@@ -18,10 +18,15 @@
import com.google.common.base.Joiner;
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for BuildQuoteHandler. */
+@RunWith(JUnit4.class)
public class BuildQuoteHandlerTest extends BuildFileIntegrationTestCase {
+ @Test
public void testClosingQuoteInserted() {
BuildFile file = createBuildFile("BUILD", "");
@@ -29,6 +34,7 @@
assertFileContents(file, "\"\"");
}
+ @Test
public void testClosingSingleQuoteInserted() {
BuildFile file = createBuildFile("BUILD", "");
@@ -36,6 +42,7 @@
assertFileContents(file, "''");
}
+ @Test
public void testClosingTripleQuoteInserted() {
BuildFile file = createBuildFile("BUILD", "");
@@ -45,6 +52,7 @@
assertFileContents(file, "\"\"\"\"\"\"");
}
+ @Test
public void testClosingTripleSingleQuoteInserted() {
BuildFile file = createBuildFile("BUILD", "");
@@ -54,6 +62,7 @@
assertFileContents(file, "''''''");
}
+ @Test
public void testOnlyCaretMovedWhenCompletingExistingClosingQuotes() {
BuildFile file = createBuildFile("BUILD", "'text<caret>'", "laterContents");
@@ -64,6 +73,7 @@
testFixture.checkResult(Joiner.on("\n").join("'text'<caret>", "laterContents"));
}
+ @Test
public void testOnlyCaretMovedWhenCompletingExistingClosingTripleQuotes() {
BuildFile file = createBuildFile("BUILD", "'''text<caret>'''", "laterContents");
@@ -82,6 +92,7 @@
testFixture.checkResult(Joiner.on("\n").join("'''text'''<caret>", "laterContents"));
}
+ @Test
public void testAdditionalTripleQuotesNotInsertedWhenClosingQuotes() {
BuildFile file = createBuildFile("BUILD", "'''text''<caret>", "laterContents");
@@ -92,6 +103,7 @@
testFixture.checkResult(Joiner.on("\n").join("'''text'''<caret>", "laterContents"));
}
+ @Test
public void testAdditionalQuoteNotInsertedWhenClosingQuotes() {
BuildFile file = createBuildFile("BUILD", "'text<caret>", "laterContents");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/EnterInLineCommentTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/EnterInLineCommentTest.java
index 554b127..2f3b0f2 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/EnterInLineCommentTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/editor/EnterInLineCommentTest.java
@@ -18,10 +18,15 @@
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.intellij.openapi.editor.Editor;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Test that comments are continued when creating a newline mid comment. */
+@RunWith(JUnit4.class)
public class EnterInLineCommentTest extends BuildFileIntegrationTestCase {
+ @Test
public void testInternalNewlineCommented() {
BuildFile file = createBuildFile("BUILD", "# first line comment", "# second line comment");
@@ -32,6 +37,7 @@
assertCaretPosition(editor, 2, 2);
}
+ @Test
public void testNewlineAtEndOfComment() {
BuildFile file = createBuildFile("BUILD", "# first line comment", "# second line comment");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/BlazePackageFindUsagesTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/BlazePackageFindUsagesTest.java
index c7f9152..f7a52f0 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/BlazePackageFindUsagesTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/BlazePackageFindUsagesTest.java
@@ -23,13 +23,18 @@
import com.google.idea.blaze.base.lang.buildfile.search.FindUsages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
* Tests that all references to a blaze package (including in the package components of labels) are
* found by the 'Find Usages' action.
*/
+@RunWith(JUnit4.class)
public class BlazePackageFindUsagesTest extends BuildFileIntegrationTestCase {
+ @Test
public void testDirectReferenceFound() {
BuildFile foo = createBuildFile("java/com/google/foo/BUILD");
@@ -46,6 +51,7 @@
assertThat(ref.getContainingFile()).isEqualTo(bar);
}
+ @Test
public void testLabelFragmentReferenceFound() {
BuildFile foo = createBuildFile("java/com/google/foo/BUILD", "java_library(name = \"lib\")");
@@ -63,6 +69,7 @@
}
/** If these don't resolve, directory rename refactoring won't update all labels correctly */
+ @Test
public void testInternalReferencesResolve() {
BuildFile buildFile =
createBuildFile(
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/ExternalFileUsagesTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/ExternalFileUsagesTest.java
index a02d996..cdb0c64 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/ExternalFileUsagesTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/ExternalFileUsagesTest.java
@@ -27,13 +27,18 @@
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
* Tests that references to external files (e.g. Java classes, text files) are found by the 'Find
* Usages' action
*/
+@RunWith(JUnit4.class)
public class ExternalFileUsagesTest extends BuildFileIntegrationTestCase {
+ @Test
public void testJavaClassUsagesFound() {
PsiFile javaFile =
createPsiFile(
@@ -56,31 +61,31 @@
assertThat(PsiUtils.getParentOfType(ref, Argument.Keyword.class)).isEqualTo(arg);
}
+ @Test
public void testTextFileUsagesFound() {
PsiFile textFile = createPsiFile("com/google/foo/data.txt");
- BuildFile buildFile =
- createBuildFile(
- "com/google/foo/BUILD",
- "filegroup(name = \"lib\", srcs = [\"data.txt\"])",
- "filegroup(name = \"lib2\", srcs = [\"//com/google/foo:data.txt\"])");
+ createBuildFile(
+ "com/google/foo/BUILD",
+ "filegroup(name = \"lib\", srcs = [\"data.txt\"])",
+ "filegroup(name = \"lib2\", srcs = [\"//com/google/foo:data.txt\"])");
PsiReference[] references = FindUsages.findAllReferences(textFile);
assertThat(references).hasLength(2);
}
+ @Test
public void testInvalidReferenceDoesntResolve() {
- BuildFile packageFoo = createBuildFile("com/google/foo/BUILD");
+ createBuildFile("com/google/foo/BUILD");
PsiFile textFileInFoo = createPsiFile("com/google/foo/data.txt");
- BuildFile packageBar =
- createBuildFile(
- "com/google/bar/BUILD", "filegroup(name = \"lib\", srcs = [\":data.txt\"])");
+ createBuildFile("com/google/bar/BUILD", "filegroup(name = \"lib\", srcs = [\":data.txt\"])");
PsiReference[] references = FindUsages.findAllReferences(textFileInFoo);
assertThat(references).isEmpty();
}
+ @Test
public void testSkylarkExtensionUsagesFound() {
BuildFile ext = createBuildFile("com/google/foo/ext.bzl", "def fn(): return");
createBuildFile(
@@ -93,6 +98,7 @@
assertThat(references).hasLength(3);
}
+ @Test
public void testSkylarkExtensionInSubDirectoryUsagesFound() {
BuildFile ext = createBuildFile("com/google/foo/subdir/ext.bzl", "def fn(): return");
createBuildFile(
@@ -105,8 +111,9 @@
assertThat(references).hasLength(3);
}
+ @Test
public void testSkylarkExtensionInSubDirectoryOfDifferentPackage() {
- BuildFile otherPkg = createBuildFile("com/google/foo/BUILD");
+ createBuildFile("com/google/foo/BUILD");
BuildFile ext = createBuildFile("com/google/foo/subdir/ext.bzl", "def fn(): return");
createBuildFile("com/google/bar/BUILD", "load('//com/google/foo:subdir/ext.bzl', 'fn')");
@@ -115,11 +122,11 @@
assertThat(references).hasLength(1);
}
+ @Test
public void testSkylarkExtensionReferencedFromSubpackage() {
- BuildFile pkg = createBuildFile("com/google/foo/BUILD");
+ createBuildFile("com/google/foo/BUILD");
BuildFile ext1 = createBuildFile("com/google/foo/subdir/testing.bzl", "def fn(): return");
- BuildFile ext2 =
- createBuildFile("com/google/foo/subdir/other.bzl", "load(':subdir/testing.bzl', 'fn')");
+ createBuildFile("com/google/foo/subdir/other.bzl", "load(':subdir/testing.bzl', 'fn')");
PsiReference[] references = FindUsages.findAllReferences(ext1);
assertThat(references).hasLength(1);
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FindParameterUsagesTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FindParameterUsagesTest.java
index b16e666..8928bef 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FindParameterUsagesTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FindParameterUsagesTest.java
@@ -23,12 +23,17 @@
import com.google.idea.blaze.base.lang.buildfile.psi.ParameterList;
import com.google.idea.blaze.base.lang.buildfile.search.FindUsages;
import com.intellij.psi.PsiReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
* Tests that usages of function parameters (i.e. by named args in funcall expressions) are found
*/
+@RunWith(JUnit4.class)
public class FindParameterUsagesTest extends BuildFileIntegrationTestCase {
+ @Test
public void testLocalReferences() {
BuildFile buildFile =
createBuildFile(
@@ -46,6 +51,7 @@
assertThat(references).hasLength(1);
}
+ @Test
public void testNonLocalReferences() {
BuildFile foo = createBuildFile("java/com/google/build_defs.bzl", "def function(arg1, arg2)");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FindRuleUsagesTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FindRuleUsagesTest.java
index 4d69567..1e81970 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FindRuleUsagesTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FindRuleUsagesTest.java
@@ -27,10 +27,15 @@
import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that usages of build rules are found */
+@RunWith(JUnit4.class)
public class FindRuleUsagesTest extends BuildFileIntegrationTestCase {
+ @Test
public void testLocalReferences() {
BuildFile buildFile =
createBuildFile(
@@ -54,6 +59,7 @@
}
// test full package references, made locally
+ @Test
public void testLocalFullReference() {
BuildFile buildFile =
createBuildFile(
@@ -71,6 +77,7 @@
assertThat(ref.getParent()).isInstanceOf(ListLiteral.class);
}
+ @Test
public void testNonLocalReferences() {
BuildFile targetFile =
createBuildFile("java/com/google/foo/BUILD", "java_library(name = \"target\")");
@@ -90,6 +97,7 @@
assertThat(ref.getContainingFile()).isEqualTo(refFile);
}
+ @Test
public void testFindUsagesWorksFromNameString() {
BuildFile targetFile =
createBuildFile("java/com/google/foo/BUILD", "java_library(name = \"tar<caret>get\")");
@@ -113,14 +121,14 @@
assertThat(ref.getContainingFile()).isEqualTo(refFile);
}
+ @Test
public void testInvalidReferenceDoesntResolve() {
// reference ":target" from another build file (missing package path in label)
BuildFile targetFile =
createBuildFile("java/com/google/foo/BUILD", "java_library(name = \"target\")");
- BuildFile refFile =
- createBuildFile(
- "java/com/google/bar/BUILD", "java_library(name = \"ref\", exports = [\":target\"])");
+ createBuildFile(
+ "java/com/google/bar/BUILD", "java_library(name = \"ref\", exports = [\":target\"])");
FuncallExpression target = targetFile.findChildByClass(FuncallExpression.class);
assertThat(target).isNotNull();
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FunctionStatementUsagesTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FunctionStatementUsagesTest.java
index 22be9b5..b03f32d 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FunctionStatementUsagesTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/FunctionStatementUsagesTest.java
@@ -26,10 +26,15 @@
import com.google.idea.blaze.base.lang.buildfile.search.FindUsages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that usages of function declarations are found */
+@RunWith(JUnit4.class)
public class FunctionStatementUsagesTest extends BuildFileIntegrationTestCase {
+ @Test
public void testLocalReferences() {
BuildFile buildFile =
createBuildFile(
@@ -47,6 +52,7 @@
assertThat(ref).isInstanceOf(FuncallExpression.class);
}
+ @Test
public void testLoadedFunctionReferences() {
BuildFile extFile =
createBuildFile("java/com/google/build_defs.bzl", "def function(name, deps)");
@@ -70,6 +76,7 @@
assertThat(ref.getParent()).isEqualTo(load);
}
+ @Test
public void testFuncallReference() {
BuildFile extFile =
createBuildFile("java/com/google/tools/build_defs.bzl", "def function(name, deps)");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/GlobFindUsagesTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/GlobFindUsagesTest.java
index c1de37e..f42ebe5 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/GlobFindUsagesTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/GlobFindUsagesTest.java
@@ -30,19 +30,25 @@
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.impl.file.impl.FileManager;
import com.intellij.testFramework.LightVirtualFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that file references in globs are included in the 'find usages' results. */
+@RunWith(JUnit4.class)
public class GlobFindUsagesTest extends BuildFileIntegrationTestCase {
+ @Test
public void testSimpleGlobReferencingSingleFile() {
PsiFile ref = createPsiFile("java/com/google/Test.java");
- BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
+ createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
PsiReference[] references = FindUsages.findAllReferences(ref);
assertThat(references).hasLength(1);
assertThat(references[0].getElement()).isInstanceOf(GlobExpression.class);
}
+ @Test
public void testSimpleGlobReferencingSingleFile2() {
PsiFile ref = createPsiFile("java/com/google/Test.java");
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['*.java'])");
@@ -54,6 +60,7 @@
assertThat(references[0].getElement()).isEqualTo(glob);
}
+ @Test
public void testSimpleGlobReferencingSingleFile3() {
PsiFile ref = createPsiFile("java/com/google/Test.java");
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['T*t.java'])");
@@ -65,6 +72,7 @@
assertThat(references[0].getElement()).isEqualTo(glob);
}
+ @Test
public void testGlobReferencingMultipleFiles() {
PsiFile ref1 = createPsiFile("java/com/google/Test.java");
PsiFile ref2 = createPsiFile("java/com/google/Foo.java");
@@ -81,6 +89,7 @@
assertThat(references[0].getElement()).isEqualTo(glob);
}
+ @Test
public void testFindsSubDirectories() {
PsiFile ref1 = createPsiFile("java/com/google/test/Test.java");
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
@@ -92,6 +101,7 @@
assertThat(references[0].getElement()).isEqualTo(glob);
}
+ @Test
public void testGlobWithExcludes() {
PsiFile test = createPsiFile("java/com/google/tests/Test.java");
PsiFile foo = createPsiFile("java/com/google/Foo.java");
@@ -109,10 +119,11 @@
assertThat(FindUsages.findAllReferences(test)).isEmpty();
}
+ @Test
public void testIncludeDirectories() {
PsiDirectory dir = createPsiDirectory("java/com/google/tests");
- PsiFile test = createPsiFile("java/com/google/tests/Test.java");
- PsiFile foo = createPsiFile("java/com/google/Foo.java");
+ createPsiFile("java/com/google/tests/Test.java");
+ createPsiFile("java/com/google/Foo.java");
BuildFile file =
createBuildFile(
"java/com/google/BUILD",
@@ -125,34 +136,37 @@
assertThat(references[0].getElement()).isEqualTo(glob);
}
+ @Test
public void testExcludeDirectories() {
PsiDirectory dir = createPsiDirectory("java/com/google/tests");
- PsiFile test = createPsiFile("java/com/google/tests/Test.java");
- PsiFile foo = createPsiFile("java/com/google/Foo.java");
+ createPsiFile("java/com/google/tests/Test.java");
+ createPsiFile("java/com/google/Foo.java");
BuildFile file =
createBuildFile(
"java/com/google/BUILD", "glob(" + " ['**/*']," + " exclude = ['BUILD'])");
- GlobExpression glob = PsiUtils.findFirstChildOfClassRecursive(file, GlobExpression.class);
+ PsiUtils.findFirstChildOfClassRecursive(file, GlobExpression.class);
PsiReference[] references = FindUsages.findAllReferences(dir);
assertThat(references).isEmpty();
}
+ @Test
public void testFilesInSubpackagesExcluded() {
BuildFile pkg = createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
BuildFile subPkg = createBuildFile("java/com/google/other/BUILD");
createFile("java/com/google/other/Other.java");
- GlobExpression glob = PsiUtils.findFirstChildOfClassRecursive(pkg, GlobExpression.class);
+ PsiUtils.findFirstChildOfClassRecursive(pkg, GlobExpression.class);
PsiReference[] references = FindUsages.findAllReferences(subPkg);
assertThat(references).isEmpty();
}
// regression test for b/29267289
+ @Test
public void testInMemoryFileHandledGracefully() {
- BuildFile pkg = createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
+ createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
LightVirtualFile inMemoryFile =
new LightVirtualFile("mockProjectViewFile", ProjectViewLanguage.INSTANCE, "");
@@ -164,6 +178,6 @@
PsiFile psiFile = fileManager.findFile(inMemoryFile);
- PsiReference[] references = FindUsages.findAllReferences(psiFile);
+ FindUsages.findAllReferences(psiFile);
}
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/LocalVariableUsagesTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/LocalVariableUsagesTest.java
index 50fafb4..9122f05 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/LocalVariableUsagesTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/findusages/LocalVariableUsagesTest.java
@@ -29,13 +29,18 @@
import com.google.idea.blaze.base.lang.buildfile.search.FindUsages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
* Tests that references to local variables are found by the 'Find Usages' action TODO: Support
* comprehension suffix, and add test for it
*/
+@RunWith(JUnit4.class)
public class LocalVariableUsagesTest extends BuildFileIntegrationTestCase {
+ @Test
public void testLocalReferences() {
BuildFile buildFile =
createBuildFile(
@@ -66,6 +71,7 @@
}
// the case where a symbol is the target of multiple assignment statements
+ @Test
public void testMultipleAssignments() {
BuildFile buildFile =
createBuildFile("java/com/google/BUILD", "var = 5", "var += 1", "var = 0");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/formatting/BuildFileFoldingBuilderTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/formatting/BuildFileFoldingBuilderTest.java
index 8581cbc..f9ac821 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/formatting/BuildFileFoldingBuilderTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/formatting/BuildFileFoldingBuilderTest.java
@@ -22,10 +22,15 @@
import com.google.idea.blaze.base.lang.buildfile.psi.LoadStatement;
import com.intellij.lang.folding.FoldingDescriptor;
import com.intellij.openapi.editor.Editor;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for {@link BuildFileFoldingBuilder}. */
+@RunWith(JUnit4.class)
public class BuildFileFoldingBuilderTest extends BuildFileIntegrationTestCase {
+ @Test
public void testEndOfFileFunctionDelcaration() {
// bug 28618935: test no NPE in the case where there's no
// statement list following the func-def colon
@@ -34,6 +39,7 @@
getFoldingRegions(file);
}
+ @Test
public void testFuncDefStatementsFolded() {
BuildFile file =
createBuildFile(
@@ -52,6 +58,7 @@
.isEqualTo(file.findFunctionInScope("function"));
}
+ @Test
public void testRulesFolded() {
BuildFile file =
createBuildFile(
@@ -66,6 +73,7 @@
assertThat(foldingRegions[0].getElement().getPsi()).isEqualTo(file.findRule("lib"));
}
+ @Test
public void testLoadStatementFolded() {
BuildFile file =
createBuildFile(
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/language/BuildFileTypeTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/language/BuildFileTypeTest.java
index 85b4d65..50a490a 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/language/BuildFileTypeTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/language/BuildFileTypeTest.java
@@ -20,15 +20,21 @@
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.intellij.psi.PsiFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that BUILD files are recognized as such */
+@RunWith(JUnit4.class)
public class BuildFileTypeTest extends BuildFileIntegrationTestCase {
+ @Test
public void testSkylarkExtensionRecognized() {
PsiFile file = createPsiFile("java/com/google/foo/build_defs.bzl");
assertThat(file).isInstanceOf(BuildFile.class);
}
+ @Test
public void testExactNameMatch() {
PsiFile file = createPsiFile("java/com/google/foo/BUILD");
assertThat(file).isInstanceOf(BuildFile.class);
@@ -40,6 +46,7 @@
* Currently, turned off by default because references won't resolve correctly -- they'll point
* back to normal BUILD files.
*/
+ @Test
public void testOtherBuildFilesNotRecognized() {
PsiFile file = createPsiFile("java/com/google/foo/BUILD.tools");
assertThat(file).isNotInstanceOf(BuildFile.class);
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/parser/BuildParserTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/parser/BuildParserTest.java
index 10b7869..1e09bc6 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/parser/BuildParserTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/parser/BuildParserTest.java
@@ -35,17 +35,23 @@
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Test for the BUILD file parser (converting lexical elements into PSI elements) */
+@RunWith(JUnit4.class)
public class BuildParserTest extends BuildFileIntegrationTestCase {
private final List<String> errors = Lists.newArrayList();
- @Override
- protected void doTearDown() {
+ @After
+ public final void doTearDown() {
errors.clear();
}
+ @Test
public void testAugmentedAssign() throws Exception {
assertThat(parse("x += 1")).isEqualTo("aug_assign(reference, int)");
assertThat(parse("x -= 1")).isEqualTo("aug_assign(reference, int)");
@@ -55,11 +61,13 @@
assertNoErrors();
}
+ @Test
public void testAssign() throws Exception {
assertThat(parse("a, b = 5\n")).isEqualTo("assignment(list(reference, target), int)");
assertNoErrors();
}
+ @Test
public void testAssign2() throws Exception {
assertThat(parse("a = b;c = d\n"))
.isEqualTo(
@@ -67,11 +75,13 @@
assertNoErrors();
}
+ @Test
public void testInvalidAssign() throws Exception {
parse("1 + (b = c)");
assertContainsErrors();
}
+ @Test
public void testTupleAssign() throws Exception {
assertThat(parse("list[0] = 5; dict['key'] = value\n"))
.isEqualTo(
@@ -82,18 +92,21 @@
assertNoErrors();
}
+ @Test
public void testPrimary() throws Exception {
assertThat(parse("f(1 + 2)"))
.isEqualTo("function_call(reference, arg_list(positional(binary_op(int, int))))");
assertNoErrors();
}
+ @Test
public void testSecondary() throws Exception {
assertThat(parse("f(1 % 2)"))
.isEqualTo("function_call(reference, arg_list(positional(binary_op(int, int))))");
assertNoErrors();
}
+ @Test
public void testDoesNotGetStuck() throws Exception {
// Make sure the parser does not get stuck when trying
// to parse an expression containing a syntax error.
@@ -103,6 +116,7 @@
parse("f(1, [x for foo foo foo foo], 3)");
}
+ @Test
public void testInvalidFunctionStatementDoesNotGetStuck() throws Exception {
// Make sure the parser does not get stuck when trying
// to parse a function statement containing a syntax error.
@@ -111,6 +125,7 @@
parse("def empty)");
}
+ @Test
public void testSubstring() throws Exception {
assertThat(parse("'FOO.CC'[:].lower()[1:]"))
.isEqualTo(
@@ -122,6 +137,7 @@
assertNoErrors();
}
+ @Test
public void testFuncallExpr() throws Exception {
assertThat(parse("foo(1, 2, bar=wiz)"))
.isEqualTo(
@@ -134,6 +150,7 @@
assertNoErrors();
}
+ @Test
public void testMethCallExpr() throws Exception {
assertThat(parse("foo.foo(1, 2, bar=wiz)"))
.isEqualTo(
@@ -144,6 +161,7 @@
assertNoErrors();
}
+ @Test
public void testChainedMethCallExpr() throws Exception {
assertThat(parse("foo.replace().split(1)"))
.isEqualTo(
@@ -152,16 +170,19 @@
assertNoErrors();
}
+ @Test
public void testPropRefExpr() throws Exception {
assertThat(parse("foo.foo")).isEqualTo("dot_expr(reference, reference)");
assertNoErrors();
}
+ @Test
public void testStringMethExpr() throws Exception {
assertThat(parse("'foo'.foo()")).isEqualTo("function_call(string, reference, arg_list)");
assertNoErrors();
}
+ @Test
public void testFuncallLocation() throws Exception {
assertThat(parse("a(b);c = d\n"))
.isEqualTo(
@@ -172,12 +193,14 @@
assertNoErrors();
}
+ @Test
public void testList() throws Exception {
assertThat(parse("[0,f(1),2]"))
.isEqualTo("list(int, function_call(reference, arg_list(positional(int))), int)");
assertNoErrors();
}
+ @Test
public void testDict() throws Exception {
assertThat(parse("{1:2,2:f(1),3:4}"))
.isEqualTo(
@@ -191,6 +214,7 @@
assertNoErrors();
}
+ @Test
public void testArgumentList() throws Exception {
assertThat(parse("f(0,g(1,2),2)"))
.isEqualTo(
@@ -204,6 +228,7 @@
assertNoErrors();
}
+ @Test
public void testForBreakContinue() throws Exception {
String parsed =
parse("def foo():", " for i in [1, 2]:", " break", " continue", " break");
@@ -217,37 +242,44 @@
assertNoErrors();
}
+ @Test
public void testEmptyTuple() throws Exception {
assertThat(parse("()")).isEqualTo("list");
assertNoErrors();
}
+ @Test
public void testTupleTrailingComma() throws Exception {
assertThat(parse("(42,)")).isEqualTo("list(int)");
assertNoErrors();
}
+ @Test
public void testSingleton() throws Exception {
assertThat(parse("(42)")) // not a tuple!
.isEqualTo("list(int)");
assertNoErrors();
}
+ @Test
public void testDictionaryLiterals() throws Exception {
assertThat(parse("{1:42}")).isEqualTo("dict(dict_entry(int, int))");
assertNoErrors();
}
+ @Test
public void testDictionaryLiterals1() throws Exception {
assertThat(parse("{}")).isEqualTo("dict");
assertNoErrors();
}
+ @Test
public void testDictionaryLiterals2() throws Exception {
assertThat(parse("{1:42,}")).isEqualTo("dict(dict_entry(int, int))");
assertNoErrors();
}
+ @Test
public void testDictionaryLiterals3() throws Exception {
assertThat(parse("{1:42,2:43,3:44}"))
.isEqualTo(
@@ -260,11 +292,13 @@
assertNoErrors();
}
+ @Test
public void testInvalidListComprehensionSyntax() throws Exception {
assertThat(parse("[x for x for y in ['a']]")).isEqualTo("list_comp(reference, reference)");
assertContainsErrors();
}
+ @Test
public void testListComprehensionEmptyList() throws Exception {
// At the moment, we just parse the components of comprehension suffixes.
assertThat(parse("['foo/%s.java' % x for x in []]"))
@@ -272,6 +306,7 @@
assertNoErrors();
}
+ @Test
public void testListComprehension() throws Exception {
assertThat(parse("['foo/%s.java' % x for x in ['bar', 'wiz', 'quux']]"))
.isEqualTo(
@@ -283,6 +318,7 @@
assertNoErrors();
}
+ @Test
public void testDoesntGetStuck2() throws Exception {
parse(
"def foo():",
@@ -298,6 +334,7 @@
assertContainsErrors();
}
+ @Test
public void testDoesntGetStuck3() throws Exception {
parse("load(*)");
parse("load()");
@@ -308,6 +345,7 @@
assertContainsErrors();
}
+ @Test
public void testExprAsStatement() throws Exception {
String parsed =
parse("li = []", "li.append('a.c')", "\"\"\" string comment \"\"\"", "foo(bar)");
@@ -322,46 +360,54 @@
assertNoErrors();
}
+ @Test
public void testPrecedence1() {
assertThat(parse("'%sx' % 'foo' + 'bar'"))
.isEqualTo("binary_op(binary_op(string, string), string)");
assertNoErrors();
}
+ @Test
public void testPrecedence2() {
assertThat(parse("('%sx' + 'foo') * 'bar'"))
.isEqualTo("binary_op(list(binary_op(string, string)), string)");
assertNoErrors();
}
+ @Test
public void testPrecedence3() {
assertThat(parse("'%sx' % ('foo' + 'bar')"))
.isEqualTo("binary_op(string, list(binary_op(string, string)))");
assertNoErrors();
}
+ @Test
public void testPrecedence4() throws Exception {
assertThat(parse("1 + - (2 - 3)"))
.isEqualTo("binary_op(int, positional(list(binary_op(int, int))))");
assertNoErrors();
}
+ @Test
public void testPrecedence5() throws Exception {
assertThat(parse("2 * x | y + 1"))
.isEqualTo("binary_op(binary_op(int, reference), binary_op(reference, int))");
assertNoErrors();
}
+ @Test
public void testNotIsIgnored() throws Exception {
assertThat(parse("not 'b'")).isEqualTo("string");
assertNoErrors();
}
+ @Test
public void testNotIn() throws Exception {
assertThat(parse("'a' not in 'b'")).isEqualTo("binary_op(string, string)");
assertNoErrors();
}
+ @Test
public void testParseBuildFileWithSingeRule() throws Exception {
ASTNode tree =
createAST(
@@ -375,6 +421,7 @@
assertNoErrors();
}
+ @Test
public void testParseBuildFileWithMultipleRules() throws Exception {
ASTNode tree =
createAST(
@@ -393,32 +440,38 @@
assertNoErrors();
}
+ @Test
public void testMissingComma() throws Exception {
// missing comma after name='foo'
parse("genrule(name = 'foo'", " srcs = ['in'])");
assertContainsError("',' expected");
}
+ @Test
public void testDoubleSemicolon() throws Exception {
parse("x = 1; ; x = 2;");
assertContainsError("expected an expression");
}
+ @Test
public void testMissingBlock() throws Exception {
parse("x = 1;", "def foo(x):", "x = 2;\n");
assertContainsError("'indent' expected");
}
+ @Test
public void testFunCallBadSyntax() throws Exception {
parse("f(1,\n");
assertContainsError("')' expected");
}
+ @Test
public void testFunCallBadSyntax2() throws Exception {
parse("f(1, 5, ,)\n");
assertContainsError("expected an expression");
}
+ @Test
public void testLoad() throws Exception {
ASTNode tree = createAST("load('file', 'foo', 'bar',)\n");
List<LoadStatement> stmts = getTopLevelNodesOfType(tree, LoadStatement.class);
@@ -430,11 +483,13 @@
assertNoErrors();
}
+ @Test
public void testLoadNoSymbol() throws Exception {
parse("load('/foo/bar/file')\n");
assertContainsError("'load' statements must include at least one loaded function");
}
+ @Test
public void testFunctionDefinition() throws Exception {
ASTNode tree =
createAST(
@@ -449,6 +504,7 @@
assertNoErrors();
}
+ @Test
public void testFunctionCall() throws Exception {
ASTNode tree = createAST("function(name = 'foo', srcs, *args, **kwargs)");
List<BuildElement> stmts = getTopLevelNodesOfType(tree, BuildElement.class);
@@ -465,6 +521,7 @@
assertNoErrors();
}
+ @Test
public void testConditionalStatement() throws Exception {
// we don't yet bother specifying which kind of conditionals we hit
assertThat(parse("if x : y elif a : b else c"))
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/refactor/FileCopyTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/refactor/FileCopyTest.java
index a882998..be78197 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/refactor/FileCopyTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/refactor/FileCopyTest.java
@@ -21,10 +21,15 @@
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.refactoring.copy.CopyHandler;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests copying files */
+@RunWith(JUnit4.class)
public class FileCopyTest extends BuildFileIntegrationTestCase {
+ @Test
public void testCopyingJavaFileReferencedByGlob() {
createDirectory("java");
PsiFile javaFile = createPsiFile("java/Test.java", "package java;", "public class Test {}");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/refactor/RenameRefactoringTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/refactor/RenameRefactoringTest.java
index ca3a792..5c057f7 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/refactor/RenameRefactoringTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/refactor/RenameRefactoringTest.java
@@ -31,10 +31,15 @@
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that BUILD file references are correctly updated when performing rename refactors. */
+@RunWith(JUnit4.class)
public class RenameRefactoringTest extends BuildFileIntegrationTestCase {
+ @Test
public void testRenameJavaClass() {
PsiFile javaFile =
createPsiFile(
@@ -70,6 +75,7 @@
assertThat(expectedNewStrings).containsExactlyElementsIn(newStrings);
}
+ @Test
public void testRenameRule() {
BuildFile fooPackage =
createBuildFile(
@@ -98,6 +104,7 @@
"top_level_ref = \"//com/google/foo:newTargetName\"");
}
+ @Test
public void testRenameSkylarkExtension() {
BuildFile extFile =
createBuildFile("java/com/google/tools/build_defs.bzl", "def function(name, deps)");
@@ -122,6 +129,7 @@
"function(name = \"name\", deps = []");
}
+ @Test
public void testRenameLoadedFunction() {
BuildFile extFile =
createBuildFile("java/com/google/tools/build_defs.bzl", "def function(name, deps)");
@@ -149,6 +157,7 @@
"action(name = \"name\", deps = []");
}
+ @Test
public void testRenameLocalVariable() {
BuildFile file = createBuildFile("java/com/google/BUILD", "a = 1", "c = a");
@@ -161,6 +170,7 @@
}
// all references, including path fragments in labels, should be renamed.
+ @Test
public void testRenameDirectory() {
createBuildFile("java/com/baz/BUILD");
createBuildFile("java/com/google/tools/BUILD");
@@ -184,6 +194,7 @@
"function(name = \"name\", deps = [\"//java/alt/baz:target\"]");
}
+ @Test
public void testRenameFunctionParameter() {
BuildFile extFile =
createBuildFile("java/com/google/tools/build_defs.bzl", "def function(name, deps)");
@@ -212,6 +223,7 @@
"function(name = \"name\", exports = []");
}
+ @Test
public void testRenameSuggestionForBuildFile() {
BuildFile buildFile = createBuildFile("java/com/google/BUILD");
RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(buildFile);
@@ -220,6 +232,7 @@
assertThat(suggestions[0]).isEqualTo("BUILD");
}
+ @Test
public void testRenameSuggestionForSkylarkFile() {
BuildFile buildFile = createBuildFile("java/com/google/tools/build_defs.bzl");
RenamePsiElementProcessor processor = RenamePsiElementProcessor.forElement(buildFile);
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/GlobReferenceTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/GlobReferenceTest.java
index 0fcd82c..62a2de8 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/GlobReferenceTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/GlobReferenceTest.java
@@ -28,10 +28,15 @@
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that glob references are resolved correctly. */
+@RunWith(JUnit4.class)
public class GlobReferenceTest extends BuildFileIntegrationTestCase {
+ @Test
public void testSimpleGlobReferencingSingleFile() {
PsiFile ref = createPsiFile("java/com/google/Test.java");
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
@@ -42,6 +47,7 @@
assertThat(references).containsExactly(ref);
}
+ @Test
public void testSimpleGlobReferencingSingleFile2() {
PsiFile ref = createPsiFile("java/com/google/Test.java");
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['*.java'])");
@@ -52,6 +58,7 @@
assertThat(references).containsExactly(ref);
}
+ @Test
public void testSimpleGlobReferencingSingleFile3() {
PsiFile ref = createPsiFile("java/com/google/Test.java");
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['T*t.java'])");
@@ -62,6 +69,7 @@
assertThat(references).containsExactly(ref);
}
+ @Test
public void testGlobReferencingMultipleFiles() {
PsiFile ref1 = createPsiFile("java/com/google/Test.java");
PsiFile ref2 = createPsiFile("java/com/google/Foo.java");
@@ -73,6 +81,7 @@
assertThat(references).containsExactly(ref1, ref2);
}
+ @Test
public void testFindsSubDirectories() {
PsiFile ref1 = createPsiFile("java/com/google/test/Test.java");
PsiFile ref2 = createPsiFile("java/com/google/Foo.java");
@@ -84,8 +93,9 @@
assertThat(references).containsExactly(ref1, ref2);
}
+ @Test
public void testGlobWithExcludes() {
- PsiFile test = createPsiFile("java/com/google/tests/Test.java");
+ createPsiFile("java/com/google/tests/Test.java");
PsiFile foo = createPsiFile("java/com/google/Foo.java");
BuildFile file =
createBuildFile(
@@ -98,6 +108,7 @@
assertThat(references).containsExactly(foo);
}
+ @Test
public void testIncludeDirectories() {
createDirectory("java/com/google/tests");
PsiFile test = createPsiFile("java/com/google/tests/Test.java");
@@ -113,6 +124,7 @@
assertThat(references).containsExactly(foo, test, test.getParent());
}
+ @Test
public void testExcludeDirectories() {
createDirectory("java/com/google/tests");
PsiFile test = createPsiFile("java/com/google/tests/Test.java");
@@ -127,9 +139,10 @@
assertThat(references).containsExactly(foo, test);
}
+ @Test
public void testFilesInSubpackagesExcluded() {
BuildFile pkg = createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
- BuildFile subPkg = createBuildFile("java/com/google/other/BUILD");
+ createBuildFile("java/com/google/other/BUILD");
createFile("java/com/google/other/Other.java");
GlobExpression glob = PsiUtils.findFirstChildOfClassRecursive(pkg, GlobExpression.class);
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/KeywordReferenceTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/KeywordReferenceTest.java
index 310375f..fd19915 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/KeywordReferenceTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/KeywordReferenceTest.java
@@ -24,10 +24,15 @@
import com.google.idea.blaze.base.lang.buildfile.psi.FunctionStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.Parameter;
import com.google.idea.blaze.base.lang.buildfile.psi.ParameterList;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that keyword references are correctly resolved. */
+@RunWith(JUnit4.class)
public class KeywordReferenceTest extends BuildFileIntegrationTestCase {
+ @Test
public void testPlainKeywordReference() {
BuildFile file =
createBuildFile(
@@ -46,6 +51,7 @@
.isEqualTo(params.findParameterByName("deps"));
}
+ @Test
public void testKwargsReference() {
BuildFile file =
createBuildFile(
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LabelReferenceTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LabelReferenceTest.java
index e3f3e7f..2e7c417 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LabelReferenceTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LabelReferenceTest.java
@@ -28,10 +28,15 @@
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that string literal references are correctly resolved. */
+@RunWith(JUnit4.class)
public class LabelReferenceTest extends BuildFileIntegrationTestCase {
+ @Test
public void testExternalFileReference() {
BuildFile file =
createBuildFile(
@@ -48,6 +53,7 @@
assertThat(strings.get(1).getReferencedElement()).isEqualTo(xmlFile);
}
+ @Test
public void testLocalRuleReference() {
BuildFile file =
createBuildFile(
@@ -73,6 +79,7 @@
assertThat(label.getReferencedElement()).isEqualTo(lib);
}
+ @Test
public void testTargetInAnotherPackageResolves() {
BuildFile targetFile = createBuildFile("java/com/google/foo/BUILD", "rule(name = \"target\")");
@@ -89,6 +96,7 @@
assertThat(depArgument.getValue().getReferencedElement()).isEqualTo(target);
}
+ @Test
public void testRuleNameDoesntCrossPackageBoundaries() {
BuildFile targetFile =
createBuildFile("java/com/google/pkg/subpkg/BUILD", "rule(name = \"target\")");
@@ -107,6 +115,7 @@
assertThat(ref.resolve()).isEqualTo(targetFile.findRule("target"));
}
+ @Test
public void testLabelWithImplicitRuleName() {
BuildFile targetFile = createBuildFile("java/com/google/foo/BUILD", "rule(name = \"foo\")");
@@ -122,6 +131,7 @@
assertThat(depArgument.getValue().getReferencedElement()).isEqualTo(target);
}
+ @Test
public void testAbsoluteLabelInSkylarkExtension() {
BuildFile targetFile = createBuildFile("java/com/google/foo/BUILD", "rule(name = \"foo\")");
@@ -136,6 +146,7 @@
assertThat(label.getReferencedElement()).isEqualTo(target);
}
+ @Test
public void testRulePreferredOverFile() {
BuildFile targetFile = createBuildFile("java/com/foo/BUILD", "java_library(name = 'lib')");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LoadedSkylarkExtensionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LoadedSkylarkExtensionTest.java
index 7152ec1..c30e57d 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LoadedSkylarkExtensionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LoadedSkylarkExtensionTest.java
@@ -22,10 +22,15 @@
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 org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that funcall references and load statement contents are correctly resolved. */
+@RunWith(JUnit4.class)
public class LoadedSkylarkExtensionTest extends BuildFileIntegrationTestCase {
+ @Test
public void testStandardLoadReference() {
BuildFile extFile =
createBuildFile("java/com/google/build_defs.bzl", "def function(name, deps)");
@@ -66,6 +71,7 @@
// assertThat(load.getImportPsiElement().getReferencedElement()).isEqualTo(extFile);
//}
+ @Test
public void testPackageLocalImportLabelFormat() {
BuildFile extFile =
createBuildFile("java/com/google/tools/build_defs.bzl", "def function(name, deps)");
@@ -78,6 +84,7 @@
assertThat(load.getImportPsiElement().getReferencedElement()).isEqualTo(extFile);
}
+ @Test
public void testMultipleImportedFunctions() {
BuildFile extFile =
createBuildFile(
@@ -100,6 +107,7 @@
assertThat(load.getImportedFunctionReferences()).isEqualTo(functions);
}
+ @Test
public void testFuncallReference() {
BuildFile extFile =
createBuildFile("java/com/google/tools/build_defs.bzl", "def function(name, deps)");
@@ -122,6 +130,7 @@
// relative paths in skylark extensions which lie in subdirectories
// are relative to the parent blaze package directory
+ @Test
public void testRelativePathInSubdirectory() {
createFile("java/com/google/BUILD");
BuildFile referencedFile =
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LocalReferenceTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LocalReferenceTest.java
index 7bff52c..efa232d 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LocalReferenceTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/LocalReferenceTest.java
@@ -24,12 +24,17 @@
import com.google.idea.blaze.base.lang.buildfile.psi.ReferenceExpression;
import com.google.idea.blaze.base.lang.buildfile.psi.TargetExpression;
import com.intellij.psi.PsiElement;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
* Tests that local references (to TargetExpressions within a given file) are correctly resolved.
*/
+@RunWith(JUnit4.class)
public class LocalReferenceTest extends BuildFileIntegrationTestCase {
+ @Test
public void testCreatesReference() {
BuildFile file = createBuildFile("java/com/google/BUILD", "a = 1", "c = a");
@@ -41,6 +46,7 @@
assertThat(ref.getReference()).isInstanceOf(LocalReference.class);
}
+ @Test
public void testReferenceResolves() {
BuildFile file = createBuildFile("java/com/google/BUILD", "a = 1", "c = a");
@@ -51,6 +57,7 @@
assertThat(referencedElement).isEqualTo(stmts[0].getLeftHandSideExpression());
}
+ @Test
public void testTargetInOuterScope() {
BuildFile file = createBuildFile("java/com/google/BUILD", "a = 1", "function(c = a)");
@@ -62,6 +69,7 @@
assertThat(ref.getReferencedElement()).isEqualTo(target);
}
+ @Test
public void testReferenceInsideFuncallExpression() {
BuildFile file = createBuildFile("java/com/google/BUILD", "a = 1", "a.function(c)");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/PackageReferenceTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/PackageReferenceTest.java
index 47d1afc..389935f 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/PackageReferenceTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/references/PackageReferenceTest.java
@@ -24,10 +24,15 @@
import com.google.idea.blaze.base.lang.buildfile.psi.StringLiteral;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.intellij.psi.PsiReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that package references in string literals are correctly resolved. */
+@RunWith(JUnit4.class)
public class PackageReferenceTest extends BuildFileIntegrationTestCase {
+ @Test
public void testDirectReferenceResolves() {
BuildFile buildFile1 = createBuildFile("java/com/google/tools/BUILD", "# contents");
@@ -46,6 +51,7 @@
assertThat(string.getReferencedElement()).isEqualTo(buildFile1);
}
+ @Test
public void testLabelFragmentResolves() {
BuildFile buildFile1 =
createBuildFile("java/com/google/tools/BUILD", "java_library(name = \"lib\")");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/search/BlazePackageTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/search/BlazePackageTest.java
index 567ad1e..5ad3bd2 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/search/BlazePackageTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/search/BlazePackageTest.java
@@ -20,10 +20,15 @@
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.intellij.psi.PsiFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for BlazePackage */
+@RunWith(JUnit4.class)
public class BlazePackageTest extends BuildFileIntegrationTestCase {
+ @Test
public void testFindPackage() {
BuildFile packageFile = createBuildFile("java/com/google/BUILD");
PsiFile subDirFile = createPsiFile("java/com/google/tools/test.txt");
@@ -32,32 +37,35 @@
assertThat(blazePackage.buildFile).isEqualTo(packageFile);
}
+ @Test
public void testScopeDoesntCrossPackageBoundary() {
BuildFile pkg = createBuildFile("java/com/google/BUILD");
BuildFile subpkg = createBuildFile("java/com/google/other/BUILD");
BlazePackage blazePackage = BlazePackage.getContainingPackage(pkg);
assertThat(blazePackage.buildFile).isEqualTo(pkg);
- assertFalse(blazePackage.getSearchScope(false).contains(subpkg.getVirtualFile()));
+ assertThat(blazePackage.getSearchScope(false).contains(subpkg.getVirtualFile())).isFalse();
}
+ @Test
public void testScopeIncludesSubdirectoriesWhichAreNotBlazePackages() {
BuildFile pkg = createBuildFile("java/com/google/BUILD");
- BuildFile subpkg = createBuildFile("java/com/google/foo/bar/BUILD");
+ createBuildFile("java/com/google/foo/bar/BUILD");
PsiFile subDirFile = createPsiFile("java/com/google/foo/test.txt");
BlazePackage blazePackage = BlazePackage.getContainingPackage(subDirFile);
assertThat(blazePackage.buildFile).isEqualTo(pkg);
- assertTrue(blazePackage.getSearchScope(false).contains(subDirFile.getVirtualFile()));
+ assertThat(blazePackage.getSearchScope(false).contains(subDirFile.getVirtualFile())).isTrue();
}
+ @Test
public void testScopeLimitedToBlazeFiles() {
BuildFile pkg = createBuildFile("java/com/google/BUILD");
- BuildFile subpkg = createBuildFile("java/com/google/foo/bar/BUILD");
+ createBuildFile("java/com/google/foo/bar/BUILD");
PsiFile subDirFile = createPsiFile("java/com/google/foo/test.txt");
BlazePackage blazePackage = BlazePackage.getContainingPackage(subDirFile);
assertThat(blazePackage.buildFile).isEqualTo(pkg);
- assertFalse(blazePackage.getSearchScope(true).contains(subDirFile.getVirtualFile()));
+ assertThat(blazePackage.getSearchScope(true).contains(subDirFile.getVirtualFile())).isFalse();
}
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/search/GlobalWordIndexTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/search/GlobalWordIndexTest.java
index 2eb828c..4fdaf86 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/search/GlobalWordIndexTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/search/GlobalWordIndexTest.java
@@ -22,18 +22,25 @@
import com.intellij.psi.search.UsageSearchContext;
import java.util.Arrays;
import org.intellij.lang.annotations.MagicConstant;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
* Test the WordScanner indexes keywords in the way we expect.<br>
* This is vital for navigation, refactoring, highlighting etc.
*/
+@RunWith(JUnit4.class)
public class GlobalWordIndexTest extends BuildFileIntegrationTestCase {
+ @Test
public void testWordsInComments() {
VirtualFile file = createFile("java/com/google/BUILD", "# words in comments");
assertContainsWords(file, UsageSearchContext.IN_COMMENTS, "words", "in", "comments");
}
+ @Test
public void testWordsInStrings() {
VirtualFile file =
createFile(
@@ -50,6 +57,7 @@
"name_without_spaces");
}
+ @Test
public void testWordsInCode() {
VirtualFile file =
createFile(
@@ -73,7 +81,7 @@
.getVirtualFilesWithWord(
word, occurenceMask, GlobalSearchScope.fileScope(getProject(), file), true);
if (!Arrays.asList(files).contains(file)) {
- fail(String.format("Word '%s' not found in file '%s'", word, file));
+ Assert.fail(String.format("Word '%s' not found in file '%s'", word, file));
}
}
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/GlobValidationTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/GlobValidationTest.java
index 3ba00e5..2715bbe 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/GlobValidationTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/GlobValidationTest.java
@@ -28,22 +28,29 @@
import com.intellij.psi.PsiFile;
import java.util.List;
import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests glob validation. */
+@RunWith(JUnit4.class)
public class GlobValidationTest extends BuildFileIntegrationTestCase {
+ @Test
public void testNormalGlob() {
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['**/*.java'])");
assertNoErrors(file);
}
+ @Test
public void testNamedIncludeArgument() {
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(include = ['**/*.java'])");
assertNoErrors(file);
}
+ @Test
public void testAllArguments() {
BuildFile file =
createBuildFile(
@@ -53,18 +60,21 @@
assertNoErrors(file);
}
+ @Test
public void testEmptyExcludeList() {
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(['**/*.java'], exclude = [])");
assertNoErrors(file);
}
+ @Test
public void testNoIncludesError() {
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(exclude = ['BUILD'])");
assertHasError(file, "Glob expression must contain at least one included string");
}
+ @Test
public void testSingletonExcludeArgumentError() {
BuildFile file =
createBuildFile("java/com/google/BUILD", "glob(['**/*.java'], exclude = 'BUILD')");
@@ -72,12 +82,14 @@
assertHasError(file, "Glob parameter 'exclude' must be a list of strings");
}
+ @Test
public void testSingletonIncludeArgumentError() {
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(include = '**/*.java')");
assertHasError(file, "Glob parameter 'include' must be a list of strings");
}
+ @Test
public void testInvalidExcludeDirectoriesValue() {
BuildFile file =
createBuildFile(
@@ -87,6 +99,7 @@
assertHasError(file, "exclude_directories parameter to glob must be 0 or 1");
}
+ @Test
public void testUnrecognizedArgumentError() {
BuildFile file =
createBuildFile(
@@ -95,12 +108,14 @@
assertHasError(file, "Unrecognized glob argument");
}
+ @Test
public void testInvalidListArgumentValue() {
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(include = foo)");
assertHasError(file, "Glob parameter 'include' must be a list of strings");
}
+ @Test
public void testLocalVariableReference() {
BuildFile file =
createBuildFile("java/com/google/BUILD", "foo = ['*.java']", "glob(include = foo)");
@@ -108,8 +123,9 @@
assertNoErrors(file);
}
+ @Test
public void testLoadedVariableReference() {
- BuildFile ext = createBuildFile("java/com/foo/vars.bzl", "LIST_VAR = ['*']");
+ createBuildFile("java/com/foo/vars.bzl", "LIST_VAR = ['*']");
BuildFile file =
createBuildFile(
"java/com/google/BUILD",
@@ -119,8 +135,9 @@
assertNoErrors(file);
}
+ @Test
public void testInvalidLoadedVariableReference() {
- BuildFile ext = createBuildFile("java/com/foo/vars.bzl", "LIST_VAR = ['*']", "def function()");
+ createBuildFile("java/com/foo/vars.bzl", "LIST_VAR = ['*']", "def function()");
BuildFile file =
createBuildFile(
"java/com/google/BUILD",
@@ -130,18 +147,21 @@
assertHasError(file, "Glob parameter 'include' must be a list of strings");
}
+ @Test
public void testUnresolvedReferenceExpression() {
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(include = ref)");
assertHasError(file, "Glob parameter 'include' must be a list of strings");
}
+ @Test
public void testPossibleListExpressionFuncallExpression() {
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(include = fn.list)");
assertNoErrors(file);
}
+ @Test
public void testPossibleListExpressionParameter() {
BuildFile file =
createBuildFile(
@@ -150,6 +170,7 @@
assertNoErrors(file);
}
+ @Test
public void testNestedGlobs() {
// blaze accepts nested globs
BuildFile file = createBuildFile("java/com/google/BUILD", "glob(glob(['*.java']))");
@@ -157,6 +178,7 @@
assertNoErrors(file);
}
+ @Test
public void testKnownInvalidResolvedListExpression() {
BuildFile file =
createBuildFile("java/com/google/BUILD", "bool_literal = True", "glob(bool_literal)");
@@ -164,6 +186,7 @@
assertHasError(file, "Glob parameter 'include' must be a list of strings");
}
+ @Test
public void testKnownInvalidResolvedString() {
BuildFile file =
createBuildFile("java/com/google/BUILD", "bool_literal = True", "glob([bool_literal])");
@@ -171,6 +194,7 @@
assertHasError(file, "Glob parameter 'include' must be a list of strings");
}
+ @Test
public void testPossibleStringLiteralIfStatement() {
BuildFile file =
createBuildFile("java/com/google/BUILD", "glob(include = ['*.java', if test : a else b])");
@@ -179,6 +203,7 @@
assertNoErrors(file);
}
+ @Test
public void testPossibleStringLiteralParameter() {
BuildFile file =
createBuildFile(
@@ -206,10 +231,8 @@
private List<Annotation> validateFile(BuildFile file) {
GlobErrorAnnotator annotator = createAnnotator(file);
- for (GlobExpression glob :
- PsiUtils.findAllChildrenOfClassRecursive(file, GlobExpression.class)) {
- annotator.visitGlobExpression(glob);
- }
+ PsiUtils.findAllChildrenOfClassRecursive(file, GlobExpression.class)
+ .forEach(annotator::visitGlobExpression);
return annotationHolder;
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewCompletionTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewCompletionTest.java
index 4e629f8..3628b85 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewCompletionTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewCompletionTest.java
@@ -27,8 +27,13 @@
import com.intellij.psi.PsiFile;
import java.util.Arrays;
import java.util.stream.Collectors;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests auto-complete in project view files */
+@RunWith(JUnit4.class)
public class ProjectViewCompletionTest extends ProjectViewIntegrationTestCase {
private PsiFile setInput(String... fileContents) {
@@ -36,10 +41,11 @@
}
private void assertResult(String... resultingFileContents) {
- String s = testFixture.getFile().getText();
+ testFixture.getFile().getText();
testFixture.checkResult(Joiner.on("\n").join(resultingFileContents));
}
+ @Test
public void testSectionTypeKeywords() {
setInput("<caret>");
String[] keywords = getCompletionItemsAsStrings();
@@ -53,12 +59,14 @@
.collect(Collectors.toList()));
}
+ @Test
public void testColonAndNewLineAndIndentInsertedAfterListSection() {
setInput("direc<caret>");
assertThat(completeIfUnique()).isTrue();
assertResult("directories:", " <caret>");
}
+ @Test
public void testWhitespaceDividerInsertedAfterScalarSection() {
setInput("impo<caret>");
@@ -71,32 +79,36 @@
assertResult("import <caret>");
}
+ @Test
public void testColonDividerAndSpaceInsertedAfterScalarSection() {
setInput("works<caret>");
assertThat(completeIfUnique()).isTrue();
assertResult("workspace_type: <caret>");
}
+ @Test
public void testNoKeywordCompletionInListItem() {
setInput("directories:", " <caret>");
String[] completionItems = getCompletionItemsAsStrings();
if (completionItems == null) {
- fail("Spurious completion. New file contents: " + testFixture.getFile().getText());
+ Assert.fail("Spurious completion. New file contents: " + testFixture.getFile().getText());
}
assertThat(completionItems).isEmpty();
}
+ @Test
public void testNoKeywordCompletionAfterKeyword() {
setInput("import <caret>");
String[] completionItems = getCompletionItemsAsStrings();
if (completionItems == null) {
- fail("Spurious completion. New file contents: " + testFixture.getFile().getText());
+ Assert.fail("Spurious completion. New file contents: " + testFixture.getFile().getText());
}
assertThat(completionItems).isEmpty();
}
+ @Test
public void testWorkspaceTypeCompletion() {
setInput("workspace_type: <caret>");
@@ -110,6 +122,7 @@
.collect(Collectors.toList()));
}
+ @Test
public void testAdditionalLanguagesCompletion() {
setInput("additional_languages:", " <caret>");
@@ -123,6 +136,7 @@
.collect(Collectors.toList()));
}
+ @Test
public void testUniqueDirectoryCompleted() {
setInput("import <caret>");
@@ -133,6 +147,7 @@
assertResult("import java<caret>");
}
+ @Test
public void testUniqueMultiSegmentDirectoryCompleted() {
setInput("import <caret>");
@@ -143,6 +158,7 @@
assertResult("import java/com/google<caret>");
}
+ @Test
public void testNonDirectoriesIgnored() {
setInput("import <caret>");
@@ -154,6 +170,7 @@
assertResult("import java/com/google<caret>");
}
+ @Test
public void testMultipleDirectoryOptions() {
createDirectory("foo");
createDirectory("bar");
@@ -173,6 +190,7 @@
assertResult("targets:", " //ostrich<caret>");
}
+ @Test
public void testRuleCompletion() {
createFile("BUILD", "java_library(name = 'lib')");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewIntegrationTestCase.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewIntegrationTestCase.java
index 151d384..96b5f8a 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewIntegrationTestCase.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewIntegrationTestCase.java
@@ -18,18 +18,22 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.BlazeIntegrationTestCase;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoderImpl;
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.base.sync.workspace.WorkspacePathResolverImpl;
+import org.junit.Before;
/** Project view file specific integration test base */
public abstract class ProjectViewIntegrationTestCase extends BlazeIntegrationTestCase {
- @Override
- protected void doSetup() {
+ @Before
+ public final void doSetup() {
mockBlazeProjectDataManager(getMockBlazeProjectData());
}
@@ -40,12 +44,17 @@
ImmutableList.of(workspaceRoot.directory()),
new ExecutionRootPath("out/crosstool/bin"),
new ExecutionRootPath("out/crosstool/gen"));
+ WorkspacePathResolver workspacePathResolver =
+ new WorkspacePathResolverImpl(workspaceRoot, fakeRoots);
+ ArtifactLocationDecoder artifactLocationDecoder =
+ new ArtifactLocationDecoderImpl(fakeRoots, workspacePathResolver);
return new BlazeProjectData(
0,
new RuleMap(ImmutableMap.of()),
fakeRoots,
new WorkingSet(ImmutableList.of(), ImmutableList.of(), ImmutableList.of()),
- new WorkspacePathResolverImpl(workspaceRoot, fakeRoots),
+ workspacePathResolver,
+ artifactLocationDecoder,
null,
null,
null,
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewParserIntegrationTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewParserIntegrationTest.java
index 68cf418..4fee948 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewParserIntegrationTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/ProjectViewParserIntegrationTest.java
@@ -28,18 +28,23 @@
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for the project view file parser */
+@RunWith(JUnit4.class)
public class ProjectViewParserIntegrationTest extends ProjectViewIntegrationTestCase {
private final List<String> errors = Lists.newArrayList();
- @Override
- protected void doSetup() {
+ @Before
+ public final void before() {
errors.clear();
- super.doSetup();
}
+ @Test
public void testStandardFile() {
assertThat(
parse(
@@ -57,6 +62,7 @@
assertNoErrors();
}
+ @Test
public void testIncludeScalarSections() {
assertThat(
parse(
@@ -79,6 +85,7 @@
assertNoErrors();
}
+ @Test
public void testUnrecognizedKeyword() {
parse("impart java/com/google/work/.blazeproject", "", "workspace_trype: intellij_plugin");
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/lexer/ProjectViewLexerTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/lexer/ProjectViewLexerTest.java
index 610aef3..8821c02 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/lexer/ProjectViewLexerTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/projectview/lexer/ProjectViewLexerTest.java
@@ -20,10 +20,15 @@
import com.google.common.base.Joiner;
import com.google.idea.blaze.base.lang.projectview.ProjectViewIntegrationTestCase;
import com.google.idea.blaze.base.lang.projectview.lexer.ProjectViewLexerBase.Token;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for the project view file lexer */
+@RunWith(JUnit4.class)
public class ProjectViewLexerTest extends ProjectViewIntegrationTestCase {
+ @Test
public void testStandardCase() {
String result =
tokenize(
@@ -47,6 +52,7 @@
"indent identifier : identifier"));
}
+ @Test
public void testIncludeScalarSections() {
String result =
tokenize(
@@ -72,6 +78,7 @@
"indent identifier"));
}
+ @Test
public void testUnrecognizedKeyword() {
String result =
tokenize(
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationGenericHandlerIntegrationTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationGenericHandlerIntegrationTest.java
index 1fe63b7..eac7ae9 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationGenericHandlerIntegrationTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationGenericHandlerIntegrationTest.java
@@ -21,24 +21,32 @@
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.BlazeIntegrationTestCase;
import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration.BlazeCommandRunConfigurationSettingsEditor;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
-import com.google.idea.blaze.base.run.confighandler.BlazeUnknownRunConfigurationHandler;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoderImpl;
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.base.sync.workspace.WorkspacePathResolverImpl;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.util.Disposer;
import org.jdom.Element;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/**
- * Integration tests for {@link BlazeCommandRunConfiguration} with {@link
- * BlazeCommandGenericRunConfigurationHandler} and {@link BlazeUnknownRunConfigurationHandler}.
+ * Integration tests for {@link BlazeCommandRunConfiguration} with a {@link
+ * BlazeCommandGenericRunConfigurationHandler}.
*/
+@RunWith(JUnit4.class)
public class BlazeCommandRunConfigurationGenericHandlerIntegrationTest
extends BlazeIntegrationTestCase {
private static final BlazeCommandName COMMAND = BlazeCommandName.fromString("command");
@@ -46,9 +54,8 @@
private BlazeCommandRunConfigurationType type;
private BlazeCommandRunConfiguration configuration;
- @Override
- protected void doSetup() throws Exception {
- super.doSetup();
+ @Before
+ public final void doSetup() throws Exception {
// Without BlazeProjectData, the configuration editor is always disabled.
mockBlazeProjectDataManager(getMockBlazeProjectData());
type = BlazeCommandRunConfigurationType.getInstance();
@@ -62,44 +69,54 @@
ImmutableList.of(workspaceRoot.directory()),
new ExecutionRootPath("out/crosstool/bin"),
new ExecutionRootPath("out/crosstool/gen"));
+ WorkspacePathResolver workspacePathResolver =
+ new WorkspacePathResolverImpl(workspaceRoot, fakeRoots);
+ ArtifactLocationDecoder artifactLocationDecoder =
+ new ArtifactLocationDecoderImpl(fakeRoots, workspacePathResolver);
return new BlazeProjectData(
0,
new RuleMap(ImmutableMap.of()),
fakeRoots,
new WorkingSet(ImmutableList.of(), ImmutableList.of(), ImmutableList.of()),
- new WorkspacePathResolverImpl(workspaceRoot, fakeRoots),
+ workspacePathResolver,
+ artifactLocationDecoder,
null,
null,
null,
null);
}
- public void testNewConfigurationHasUnknownHandler() {
- assertThat(configuration.getHandler()).isInstanceOf(BlazeUnknownRunConfigurationHandler.class);
+ @Test
+ public void testNewConfigurationHasGenericHandler() {
+ assertThat(configuration.getHandler())
+ .isInstanceOf(BlazeCommandGenericRunConfigurationHandler.class);
}
+ @Test
public void testSetTargetNullMakesGenericHandler() {
configuration.setTarget(null);
assertThat(configuration.getHandler())
.isInstanceOf(BlazeCommandGenericRunConfigurationHandler.class);
}
+ @Test
public void testTargetExpressionMakesGenericHandler() {
configuration.setTarget(TargetExpression.fromString("//..."));
assertThat(configuration.getHandler())
.isInstanceOf(BlazeCommandGenericRunConfigurationHandler.class);
}
+ @Test
public void testReadAndWriteMatches() throws Exception {
TargetExpression targetExpression = TargetExpression.fromString("//...");
configuration.setTarget(targetExpression);
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) configuration.getHandler();
- handler.setCommand(COMMAND);
- handler.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
- handler.setExeFlags(ImmutableList.of("--exeFlag1"));
- handler.setBlazeBinary("/usr/bin/blaze");
+ BlazeCommandRunConfigurationCommonState state =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
+ state.setCommand(COMMAND);
+ state.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
+ state.setExeFlags(ImmutableList.of("--exeFlag1"));
+ state.setBlazeBinary("/usr/bin/blaze");
Element element = new Element("test");
configuration.writeExternal(element);
@@ -111,14 +128,15 @@
assertThat(readConfiguration.getHandler())
.isInstanceOf(BlazeCommandGenericRunConfigurationHandler.class);
- BlazeCommandGenericRunConfigurationHandler readHandler =
- (BlazeCommandGenericRunConfigurationHandler) readConfiguration.getHandler();
- assertThat(readHandler.getCommand()).isEqualTo(COMMAND);
- assertThat(readHandler.getAllBlazeFlags()).containsExactly("--flag1", "--flag2").inOrder();
- assertThat(readHandler.getAllExeFlags()).containsExactly("--exeFlag1");
- assertThat(readHandler.getBlazeBinary()).isEqualTo("/usr/bin/blaze");
+ BlazeCommandRunConfigurationCommonState readState =
+ (BlazeCommandRunConfigurationCommonState) readConfiguration.getHandler().getState();
+ assertThat(readState.getCommand()).isEqualTo(COMMAND);
+ assertThat(readState.getBlazeFlags()).containsExactly("--flag1", "--flag2").inOrder();
+ assertThat(readState.getExeFlags()).containsExactly("--exeFlag1");
+ assertThat(readState.getBlazeBinary()).isEqualTo("/usr/bin/blaze");
}
+ @Test
public void testReadAndWriteHandlesNulls() throws Exception {
Element element = new Element("test");
configuration.writeExternal(element);
@@ -128,59 +146,22 @@
assertThat(readConfiguration.getTarget()).isEqualTo(configuration.getTarget());
assertThat(readConfiguration.getHandler())
- .isInstanceOf(BlazeUnknownRunConfigurationHandler.class);
- }
-
- public void testEditorWithUnknownHandlerDoesNotApplyTo() throws ConfigurationException {
- assertThat(configuration.getTarget()).isNull();
- assertThat(configuration.getHandler()).isInstanceOf(BlazeUnknownRunConfigurationHandler.class);
-
- BlazeCommandRunConfigurationSettingsEditor editor =
- new BlazeCommandRunConfigurationSettingsEditor(configuration);
- // Because the configuration's handler is BlazeUnknownRunConfigurationHandler,
- // resetting the editor to it will leave it in the disabled state.
- editor.resetFrom(configuration);
-
- BlazeCommandRunConfiguration readConfiguration =
- type.getFactory().createTemplateConfiguration(getProject());
- TargetExpression targetExpression = TargetExpression.fromString("//...");
- readConfiguration.setTarget(targetExpression);
-
- BlazeCommandGenericRunConfigurationHandler readHandler =
- (BlazeCommandGenericRunConfigurationHandler) readConfiguration.getHandler();
- readHandler.setCommand(COMMAND);
- readHandler.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
- readHandler.setExeFlags(ImmutableList.of("--exeFlag1"));
- readHandler.setBlazeBinary("/usr/bin/blaze");
-
- // The editor is disabled, making applyEditorTo a no-op.
- editor.applyEditorTo(readConfiguration);
-
- assertThat(readConfiguration.getTarget()).isEqualTo(targetExpression);
- assertThat(readConfiguration.getHandler())
.isInstanceOf(BlazeCommandGenericRunConfigurationHandler.class);
-
- readHandler = (BlazeCommandGenericRunConfigurationHandler) readConfiguration.getHandler();
- assertThat(readHandler.getCommand()).isEqualTo(COMMAND);
- assertThat(readHandler.getAllBlazeFlags()).containsExactly("--flag1", "--flag2").inOrder();
- assertThat(readHandler.getAllExeFlags()).containsExactly("--exeFlag1");
- assertThat(readHandler.getBlazeBinary()).isEqualTo("/usr/bin/blaze");
-
- Disposer.dispose(editor);
}
+ @Test
public void testEditorApplyToAndResetFromMatches() throws ConfigurationException {
BlazeCommandRunConfigurationSettingsEditor editor =
new BlazeCommandRunConfigurationSettingsEditor(configuration);
TargetExpression targetExpression = TargetExpression.fromString("//...");
configuration.setTarget(targetExpression);
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) configuration.getHandler();
- handler.setCommand(COMMAND);
- handler.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
- handler.setExeFlags(ImmutableList.of("--exeFlag1"));
- handler.setBlazeBinary("/usr/bin/blaze");
+ BlazeCommandRunConfigurationCommonState state =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
+ state.setCommand(COMMAND);
+ state.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
+ state.setExeFlags(ImmutableList.of("--exeFlag1"));
+ state.setBlazeBinary("/usr/bin/blaze");
editor.resetFrom(configuration);
BlazeCommandRunConfiguration readConfiguration =
@@ -191,16 +172,17 @@
assertThat(readConfiguration.getHandler())
.isInstanceOf(BlazeCommandGenericRunConfigurationHandler.class);
- BlazeCommandGenericRunConfigurationHandler readHandler =
- (BlazeCommandGenericRunConfigurationHandler) readConfiguration.getHandler();
- assertThat(readHandler.getCommand()).isEqualTo(handler.getCommand());
- assertThat(readHandler.getAllBlazeFlags()).isEqualTo(handler.getAllBlazeFlags());
- assertThat(readHandler.getAllExeFlags()).isEqualTo(handler.getAllExeFlags());
- assertThat(readHandler.getBlazeBinary()).isEqualTo(handler.getBlazeBinary());
+ BlazeCommandRunConfigurationCommonState readState =
+ (BlazeCommandRunConfigurationCommonState) readConfiguration.getHandler().getState();
+ assertThat(readState.getCommand()).isEqualTo(state.getCommand());
+ assertThat(readState.getBlazeFlags()).isEqualTo(state.getBlazeFlags());
+ assertThat(readState.getExeFlags()).isEqualTo(state.getExeFlags());
+ assertThat(readState.getBlazeBinary()).isEqualTo(state.getBlazeBinary());
Disposer.dispose(editor);
}
+ @Test
public void testEditorApplyToAndResetFromHandlesNulls() throws ConfigurationException {
BlazeCommandRunConfigurationSettingsEditor editor =
new BlazeCommandRunConfigurationSettingsEditor(configuration);
@@ -210,8 +192,8 @@
assertThat(configuration.getTarget()).isNull();
assertThat(configuration.getHandler())
.isInstanceOf(BlazeCommandGenericRunConfigurationHandler.class);
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) configuration.getHandler();
+ BlazeCommandRunConfigurationCommonState state =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
editor.resetFrom(configuration);
@@ -220,12 +202,12 @@
TargetExpression targetExpression = TargetExpression.fromString("//...");
readConfiguration.setTarget(targetExpression);
- BlazeCommandGenericRunConfigurationHandler readHandler =
- (BlazeCommandGenericRunConfigurationHandler) readConfiguration.getHandler();
- readHandler.setCommand(COMMAND);
- readHandler.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
- readHandler.setExeFlags(ImmutableList.of("--exeFlag1"));
- readHandler.setBlazeBinary("/usr/bin/blaze");
+ BlazeCommandRunConfigurationCommonState readState =
+ (BlazeCommandRunConfigurationCommonState) readConfiguration.getHandler().getState();
+ readState.setCommand(COMMAND);
+ readState.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
+ readState.setExeFlags(ImmutableList.of("--exeFlag1"));
+ readState.setBlazeBinary("/usr/bin/blaze");
editor.applyEditorTo(readConfiguration);
@@ -233,11 +215,11 @@
assertThat(configuration.getHandler())
.isInstanceOf(BlazeCommandGenericRunConfigurationHandler.class);
- readHandler = (BlazeCommandGenericRunConfigurationHandler) readConfiguration.getHandler();
- assertThat(readHandler.getCommand()).isEqualTo(handler.getCommand());
- assertThat(readHandler.getAllBlazeFlags()).isEqualTo(handler.getAllBlazeFlags());
- assertThat(readHandler.getAllExeFlags()).isEqualTo(handler.getAllExeFlags());
- assertThat(readHandler.getBlazeBinary()).isEqualTo(handler.getBlazeBinary());
+ readState = (BlazeCommandRunConfigurationCommonState) readConfiguration.getHandler().getState();
+ assertThat(readState.getCommand()).isEqualTo(state.getCommand());
+ assertThat(readState.getBlazeFlags()).isEqualTo(state.getBlazeFlags());
+ assertThat(readState.getExeFlags()).isEqualTo(state.getExeFlags());
+ assertThat(readState.getBlazeBinary()).isEqualTo(state.getBlazeBinary());
Disposer.dispose(editor);
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationSettingsEditorTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationSettingsEditorTest.java
index a0a044d..56ffef1 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationSettingsEditorTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationSettingsEditorTest.java
@@ -20,26 +20,33 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.BlazeIntegrationTestCase;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration.BlazeCommandRunConfigurationSettingsEditor;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoderImpl;
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.base.sync.workspace.WorkspacePathResolverImpl;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.util.Disposer;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for {@link BlazeCommandRunConfiguration.BlazeCommandRunConfigurationSettingsEditor}. */
+@RunWith(JUnit4.class)
public class BlazeCommandRunConfigurationSettingsEditorTest extends BlazeIntegrationTestCase {
private BlazeCommandRunConfigurationType type;
private BlazeCommandRunConfiguration configuration;
- @Override
- protected void doSetup() throws Exception {
- super.doSetup();
+ @Before
+ public final void doSetup() throws Exception {
// Without BlazeProjectData, the configuration editor is always disabled.
mockBlazeProjectDataManager(getMockBlazeProjectData());
type = BlazeCommandRunConfigurationType.getInstance();
@@ -53,18 +60,24 @@
ImmutableList.of(workspaceRoot.directory()),
new ExecutionRootPath("out/crosstool/bin"),
new ExecutionRootPath("out/crosstool/gen"));
+ WorkspacePathResolver workspacePathResolver =
+ new WorkspacePathResolverImpl(workspaceRoot, fakeRoots);
+ ArtifactLocationDecoder artifactLocationDecoder =
+ new ArtifactLocationDecoderImpl(fakeRoots, workspacePathResolver);
return new BlazeProjectData(
0,
new RuleMap(ImmutableMap.of()),
fakeRoots,
new WorkingSet(ImmutableList.of(), ImmutableList.of(), ImmutableList.of()),
- new WorkspacePathResolverImpl(workspaceRoot, fakeRoots),
+ workspacePathResolver,
+ artifactLocationDecoder,
null,
null,
null,
null);
}
+ @Test
public void testEditorApplyToAndResetFromMatches() throws ConfigurationException {
BlazeCommandRunConfigurationSettingsEditor editor =
new BlazeCommandRunConfigurationSettingsEditor(configuration);
@@ -81,6 +94,7 @@
Disposer.dispose(editor);
}
+ @Test
public void testEditorApplyToAndResetFromHandlesNulls() throws ConfigurationException {
BlazeCommandRunConfigurationSettingsEditor editor =
new BlazeCommandRunConfigurationSettingsEditor(configuration);
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/run/TestRuleHeuristicTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/run/TestRuleHeuristicTest.java
index 16e7de0..aafa355 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/run/TestRuleHeuristicTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/run/TestRuleHeuristicTest.java
@@ -25,10 +25,15 @@
import com.google.idea.blaze.base.model.primitives.Label;
import java.io.File;
import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Integration tests for {@link TestRuleHeuristic}. */
+@RunWith(JUnit4.class)
public class TestRuleHeuristicTest extends BlazeIntegrationTestCase {
+ @Test
public void testTestSizeMatched() throws Exception {
File source = new File("java/com/foo/FooTest.java");
Collection<RuleIdeInfo> rules =
@@ -47,6 +52,7 @@
assertThat(match).isEqualTo(new Label("//foo:test2"));
}
+ @Test
public void testRuleNameMatched() throws Exception {
File source = new File("java/com/foo/FooTest.java");
Collection<RuleIdeInfo> rules =
@@ -57,6 +63,7 @@
assertThat(match).isEqualTo(new Label("//foo:FooTest"));
}
+ @Test
public void testNoMatchFallBackToFirstRule() throws Exception {
File source = new File("java/com/foo/FooTest.java");
ImmutableList<RuleIdeInfo> rules =
@@ -75,6 +82,7 @@
assertThat(match).isEqualTo(new Label("//bar:BarTest"));
}
+ @Test
public void testRuleNameCheckedBeforeTestSize() throws Exception {
File source = new File("java/com/foo/FooTest.java");
ImmutableList<RuleIdeInfo> rules =
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/sync/ImportRootsTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/sync/ImportRootsTest.java
index 6a2dadf..139ca30 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/sync/ImportRootsTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/sync/ImportRootsTest.java
@@ -26,10 +26,15 @@
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.sync.projectview.ImportRoots;
import java.util.stream.Collectors;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for ImportRoots */
+@RunWith(JUnit4.class)
public class ImportRootsTest extends BlazeIntegrationTestCase {
+ @Test
public void testBazelArtifactDirectoriesExcluded() {
ImportRoots importRoots =
ImportRoots.builder(workspaceRoot, BuildSystem.Bazel)
@@ -52,6 +57,7 @@
assertThat(artifactDirs).contains("bazel-" + workspaceRoot.directory().getName());
}
+ @Test
public void testNoAddedExclusionsWithoutWorkspaceRootInclusion() {
ImportRoots importRoots =
ImportRoots.builder(workspaceRoot, BuildSystem.Bazel)
@@ -62,6 +68,7 @@
assertThat(importRoots.excludeDirectories()).isEmpty();
}
+ @Test
public void testNoAddedExclusionsForBlaze() {
ImportRoots importRoots =
ImportRoots.builder(workspaceRoot, BuildSystem.Blaze)
@@ -73,6 +80,7 @@
}
// if the workspace root is an included directory, all rules should be imported as sources.
+ @Test
public void testAllLabelsIncludedUnderWorkspaceRoot() {
ImportRoots importRoots =
ImportRoots.builder(workspaceRoot, BuildSystem.Blaze)
@@ -83,6 +91,7 @@
assertThat(importRoots.importAsSource(new Label("//foo/bar:target"))).isTrue();
}
+ @Test
public void testNonOverlappingDirectoriesAreNotFilteredOut() {
ImportRoots importRoots =
ImportRoots.builder(workspaceRoot, BuildSystem.Blaze)
@@ -97,6 +106,7 @@
new WorkspacePath("root1"));
}
+ @Test
public void testOverlappingDirectoriesAreFilteredOut() {
ImportRoots importRoots =
ImportRoots.builder(workspaceRoot, BuildSystem.Blaze)
@@ -107,6 +117,7 @@
assertThat(importRoots.rootDirectories()).containsExactly(new WorkspacePath("root"));
}
+ @Test
public void testWorkspaceRootIsOnlyDirectoryLeft() {
ImportRoots importRoots =
ImportRoots.builder(workspaceRoot, BuildSystem.Blaze)
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/lexer/AbstractLexerTest.java b/base/tests/unittests/com/google/idea/blaze/base/lang/buildfile/lexer/AbstractLexerTest.java
similarity index 98%
rename from base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/lexer/AbstractLexerTest.java
rename to base/tests/unittests/com/google/idea/blaze/base/lang/buildfile/lexer/AbstractLexerTest.java
index d753970..12002b6 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/lexer/AbstractLexerTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/lang/buildfile/lexer/AbstractLexerTest.java
@@ -19,12 +19,11 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import org.junit.Ignore;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
/** Tests of tokenization behavior of {@link BuildLexerBase}. */
-@RunWith(JUnit4.class)
+@Ignore
public abstract class AbstractLexerTest {
private final BuildLexerBase.LexerMode mode;
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/lexer/BlazeLexerTest.java b/base/tests/unittests/com/google/idea/blaze/base/lang/buildfile/lexer/BlazeLexerTest.java
similarity index 100%
rename from base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/lexer/BlazeLexerTest.java
rename to base/tests/unittests/com/google/idea/blaze/base/lang/buildfile/lexer/BlazeLexerTest.java
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/lexer/HighlightingLexerTest.java b/base/tests/unittests/com/google/idea/blaze/base/lang/buildfile/lexer/HighlightingLexerTest.java
similarity index 98%
rename from base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/lexer/HighlightingLexerTest.java
rename to base/tests/unittests/com/google/idea/blaze/base/lang/buildfile/lexer/HighlightingLexerTest.java
index 3b87a83..800d6cf 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/lexer/HighlightingLexerTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/lang/buildfile/lexer/HighlightingLexerTest.java
@@ -26,8 +26,7 @@
* BuildLexerBase.LexerMode})
*/
@RunWith(JUnit4.class)
-public class HighlightingLexerTest
- extends com.google.idea.blaze.base.lang.buildfile.lexer.AbstractLexerTest {
+public class HighlightingLexerTest extends AbstractLexerTest {
public HighlightingLexerTest() {
super(BuildLexerBase.LexerMode.SyntaxHighlighting);
diff --git a/base/tests/unittests/com/google/idea/blaze/base/rulemaps/ReverseDependencyMapTest.java b/base/tests/unittests/com/google/idea/blaze/base/rulemaps/ReverseDependencyMapTest.java
index 310b7c3..1dbbbce 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/rulemaps/ReverseDependencyMapTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/rulemaps/ReverseDependencyMapTest.java
@@ -21,8 +21,9 @@
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.ideinfo.RuleMapBuilder;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.Label;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
@@ -56,9 +57,12 @@
.setKind("java_library"))
.build();
- ImmutableMultimap<Label, Label> reverseDependencies =
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
- assertThat(reverseDependencies).containsEntry(new Label("//l:l2"), new Label("//l:l1"));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l2")),
+ RuleKey.forPlainTarget(new Label("//l:l1")));
}
@Test
@@ -85,10 +89,16 @@
.setKind("java_library"))
.build();
- ImmutableMultimap<Label, Label> reverseDependencies =
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
- assertThat(reverseDependencies).containsEntry(new Label("//l:l2"), new Label("//l:l1"));
- assertThat(reverseDependencies).containsEntry(new Label("//l:l3"), new Label("//l:l1"));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l2")),
+ RuleKey.forPlainTarget(new Label("//l:l1")));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l3")),
+ RuleKey.forPlainTarget(new Label("//l:l1")));
}
@Test
@@ -115,10 +125,16 @@
.setKind("java_library"))
.build();
- ImmutableMultimap<Label, Label> reverseDependencies =
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
- assertThat(reverseDependencies).containsEntry(new Label("//l:l3"), new Label("//l:l1"));
- assertThat(reverseDependencies).containsEntry(new Label("//l:l3"), new Label("//l:l2"));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l3")),
+ RuleKey.forPlainTarget(new Label("//l:l1")));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l3")),
+ RuleKey.forPlainTarget(new Label("//l:l2")));
}
@Test
@@ -157,17 +173,28 @@
.setKind("java_library"))
.build();
- ImmutableMultimap<Label, Label> reverseDependencies =
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
- assertThat(reverseDependencies).containsEntry(new Label("//l:l3"), new Label("//l:l1"));
- assertThat(reverseDependencies).containsEntry(new Label("//l:l3"), new Label("//l:l2"));
- assertThat(reverseDependencies).containsEntry(new Label("//l:l3"), new Label("//l:l4"));
- assertThat(reverseDependencies).containsEntry(new Label("//l:l4"), new Label("//l:l5"));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l3")),
+ RuleKey.forPlainTarget(new Label("//l:l1")));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l3")),
+ RuleKey.forPlainTarget(new Label("//l:l2")));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l3")),
+ RuleKey.forPlainTarget(new Label("//l:l4")));
+ assertThat(reverseDependencies)
+ .containsEntry(
+ RuleKey.forPlainTarget(new Label("//l:l4")),
+ RuleKey.forPlainTarget(new Label("//l:l5")));
}
private static ArtifactLocation sourceRoot(String relativePath) {
return ArtifactLocation.builder()
- .setRootPath("/")
.setRelativePath(relativePath)
.setIsSource(true)
.build();
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationTest.java
index 334557e..b8f8b22 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/BlazeCommandRunConfigurationTest.java
@@ -58,8 +58,6 @@
BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
- this.configuration = this.type.getFactory().createTemplateConfiguration(project);
-
applicationServices.register(ExperimentService.class, new MockExperimentService());
applicationServices.register(RuleFinder.class, new MockRuleFinder());
ExtensionPointImpl<BlazeCommandRunConfigurationHandlerProvider> handlerProviderEp =
@@ -67,6 +65,8 @@
BlazeCommandRunConfigurationHandlerProvider.EP_NAME,
BlazeCommandRunConfigurationHandlerProvider.class);
handlerProviderEp.registerExtension(new MockBlazeCommandRunConfigurationHandlerProvider());
+
+ this.configuration = this.type.getFactory().createTemplateConfiguration(project);
}
@Test
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/RuleNameHeuristicTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/RuleNameHeuristicTest.java
index 1cb0276..1dbec9d 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/run/RuleNameHeuristicTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/RuleNameHeuristicTest.java
@@ -49,6 +49,29 @@
}
@Test
+ public void testPredicateMatchingNameAndPath() throws Exception {
+ File source = new File("java/com/foo/FooTest.java");
+ RuleIdeInfo rule =
+ RuleIdeInfo.builder().setLabel("//foo:foo/FooTest").setKind("java_test").build();
+ assertThat(new RuleNameHeuristic().matchesSource(rule, source, null)).isTrue();
+ }
+
+ @Test
+ public void testPredicateNotMatchingForPartialOverlap() throws Exception {
+ File source = new File("java/com/foo/BarFooTest.java");
+ RuleIdeInfo rule = RuleIdeInfo.builder().setLabel("//foo:FooTest").setKind("java_test").build();
+ assertThat(new RuleNameHeuristic().matchesSource(rule, source, null)).isFalse();
+ }
+
+ @Test
+ public void testPredicateNotMatchingIncorrectPath() throws Exception {
+ File source = new File("java/com/foo/FooTest.java");
+ RuleIdeInfo rule =
+ RuleIdeInfo.builder().setLabel("//foo:bar/FooTest").setKind("java_test").build();
+ assertThat(new RuleNameHeuristic().matchesSource(rule, source, null)).isFalse();
+ }
+
+ @Test
public void testPredicateDifferentName() throws Exception {
File source = new File("java/com/foo/FooTest.java");
RuleIdeInfo rule = RuleIdeInfo.builder().setLabel("//foo:ForTest").setKind("java_test").build();
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationHandlerTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationHandlerTest.java
deleted file mode 100644
index 64d3900..0000000
--- a/base/tests/unittests/com/google/idea/blaze/base/run/confighandler/BlazeCommandGenericRunConfigurationHandlerTest.java
+++ /dev/null
@@ -1,158 +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.run.confighandler;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.idea.blaze.base.BlazeTestCase;
-import com.google.idea.blaze.base.command.BlazeCommandName;
-import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
-import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler.BlazeCommandGenericRunConfigurationHandlerEditor;
-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.intellij.ide.ui.UISettings;
-import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.util.InvalidDataException;
-import org.jdom.Element;
-import org.jetbrains.annotations.NotNull;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link BlazeCommandGenericRunConfigurationHandler}. */
-@RunWith(JUnit4.class)
-public class BlazeCommandGenericRunConfigurationHandlerTest extends BlazeTestCase {
- private static final BlazeImportSettings DUMMY_IMPORT_SETTINGS =
- new BlazeImportSettings("", "", "", "", "", Blaze.BuildSystem.Blaze);
- private static final BlazeCommandName COMMAND = BlazeCommandName.fromString("command");
-
- private final BlazeCommandRunConfigurationType type = new BlazeCommandRunConfigurationType();
- private BlazeCommandRunConfiguration configuration;
- private BlazeCommandGenericRunConfigurationHandler handler;
-
- @Override
- protected void initTest(
- @NotNull Container applicationServices, @NotNull Container projectServices) {
- super.initTest(applicationServices, projectServices);
-
- applicationServices.register(UISettings.class, new UISettings());
- projectServices.register(
- BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
- BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
-
- configuration = type.getFactory().createTemplateConfiguration(project);
- handler = new BlazeCommandGenericRunConfigurationHandler(configuration);
- }
-
- @Test
- public void readAndWriteShouldMatch() throws InvalidDataException {
- handler.setCommand(COMMAND);
- handler.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
- handler.setExeFlags(ImmutableList.of("--exeFlag1"));
- handler.setBlazeBinary("/usr/bin/blaze");
-
- Element element = new Element("test");
- handler.writeExternal(element);
- BlazeCommandRunConfiguration readConfiguration =
- type.getFactory().createTemplateConfiguration(project);
- BlazeCommandGenericRunConfigurationHandler readHandler =
- new BlazeCommandGenericRunConfigurationHandler(readConfiguration);
- readHandler.readExternal(element);
-
- assertThat(readHandler.getCommand()).isEqualTo(COMMAND);
- assertThat(readHandler.getAllBlazeFlags()).containsExactly("--flag1", "--flag2").inOrder();
- assertThat(readHandler.getAllExeFlags()).containsExactly("--exeFlag1");
- assertThat(readHandler.getBlazeBinary()).isEqualTo("/usr/bin/blaze");
- }
-
- @Test
- public void readAndWriteShouldHandleNulls() throws InvalidDataException {
- Element element = new Element("test");
- handler.writeExternal(element);
- BlazeCommandRunConfiguration readConfiguration =
- type.getFactory().createTemplateConfiguration(project);
- BlazeCommandGenericRunConfigurationHandler readHandler =
- new BlazeCommandGenericRunConfigurationHandler(readConfiguration);
- readHandler.readExternal(element);
-
- assertThat(readHandler.getCommand()).isEqualTo(handler.getCommand());
- assertThat(readHandler.getAllBlazeFlags()).isEqualTo(handler.getAllBlazeFlags());
- assertThat(readHandler.getAllExeFlags()).isEqualTo(handler.getAllExeFlags());
- assertThat(readHandler.getBlazeBinary()).isEqualTo(handler.getBlazeBinary());
- }
-
- @Test
- public void readShouldOmitEmptyFlags() throws InvalidDataException {
- handler.setBlazeFlags(Lists.newArrayList("hi ", "", "I'm", " ", "\t", "Josh\r\n", "\n"));
- handler.setExeFlags(Lists.newArrayList("hi ", "", "I'm", " ", "\t", "Josh\r\n", "\n"));
-
- Element element = new Element("test");
- handler.writeExternal(element);
- BlazeCommandRunConfiguration readConfiguration =
- type.getFactory().createTemplateConfiguration(project);
- BlazeCommandGenericRunConfigurationHandler readHandler =
- new BlazeCommandGenericRunConfigurationHandler(readConfiguration);
- readHandler.readExternal(element);
-
- assertThat(readHandler.getAllBlazeFlags()).containsExactly("hi", "I'm", "Josh").inOrder();
- assertThat(readHandler.getAllExeFlags()).containsExactly("hi", "I'm", "Josh").inOrder();
- }
-
- @Test
- public void editorApplyToAndResetFromShouldMatch() throws ConfigurationException {
- BlazeCommandGenericRunConfigurationHandlerEditor editor =
- new BlazeCommandGenericRunConfigurationHandlerEditor(handler);
-
- handler.setCommand(COMMAND);
- handler.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
- handler.setExeFlags(ImmutableList.of("--exeFlag1", "--exeFlag2"));
- handler.setBlazeBinary("/usr/bin/blaze");
-
- editor.resetEditorFrom(handler);
- BlazeCommandRunConfiguration readConfiguration =
- type.getFactory().createTemplateConfiguration(project);
- BlazeCommandGenericRunConfigurationHandler readHandler =
- new BlazeCommandGenericRunConfigurationHandler(readConfiguration);
- editor.applyEditorTo(readHandler);
-
- assertThat(readHandler.getCommand()).isEqualTo(handler.getCommand());
- assertThat(readHandler.getAllBlazeFlags()).isEqualTo(handler.getAllBlazeFlags());
- assertThat(readHandler.getAllExeFlags()).isEqualTo(handler.getAllExeFlags());
- assertThat(readHandler.getBlazeBinary()).isEqualTo(handler.getBlazeBinary());
- }
-
- @Test
- public void editorApplyToAndResetFromShouldHandleNulls() throws ConfigurationException {
- BlazeCommandGenericRunConfigurationHandlerEditor editor =
- new BlazeCommandGenericRunConfigurationHandlerEditor(handler);
-
- editor.resetEditorFrom(handler);
- BlazeCommandRunConfiguration readConfiguration =
- type.getFactory().createTemplateConfiguration(project);
- BlazeCommandGenericRunConfigurationHandler readHandler =
- new BlazeCommandGenericRunConfigurationHandler(readConfiguration);
- editor.applyEditorTo(readHandler);
-
- assertThat(readHandler.getCommand()).isEqualTo(handler.getCommand());
- assertThat(readHandler.getAllBlazeFlags()).isEqualTo(handler.getAllBlazeFlags());
- assertThat(readHandler.getAllExeFlags()).isEqualTo(handler.getAllExeFlags());
- assertThat(readHandler.getBlazeBinary()).isEqualTo(handler.getBlazeBinary());
- }
-}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/confighandler/BlazeUnknownRunConfigurationHandlerTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/confighandler/BlazeUnknownRunConfigurationHandlerTest.java
deleted file mode 100644
index 7752f26..0000000
--- a/base/tests/unittests/com/google/idea/blaze/base/run/confighandler/BlazeUnknownRunConfigurationHandlerTest.java
+++ /dev/null
@@ -1,159 +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.run.confighandler;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.google.idea.blaze.base.BlazeTestCase;
-import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
-import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-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.intellij.ide.ui.UISettings;
-import com.intellij.openapi.util.InvalidDataException;
-import java.io.StringReader;
-import org.jdom.Element;
-import org.jdom.input.SAXBuilder;
-import org.jdom.output.Format;
-import org.jdom.output.XMLOutputter;
-import org.jetbrains.annotations.NotNull;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/** Tests for {@link BlazeUnknownRunConfigurationHandler}. */
-@RunWith(JUnit4.class)
-public class BlazeUnknownRunConfigurationHandlerTest extends BlazeTestCase {
- private static final BlazeImportSettings DUMMY_IMPORT_SETTINGS =
- new BlazeImportSettings("", "", "", "", "", Blaze.BuildSystem.Blaze);
-
- private final BlazeCommandRunConfigurationType type = new BlazeCommandRunConfigurationType();
- private BlazeCommandRunConfiguration configuration;
- private BlazeUnknownRunConfigurationHandler handler;
-
- @Override
- protected void initTest(
- @NotNull Container applicationServices, @NotNull Container projectServices) {
- super.initTest(applicationServices, projectServices);
-
- applicationServices.register(UISettings.class, new UISettings());
- projectServices.register(
- BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
- BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
-
- configuration = type.getFactory().createTemplateConfiguration(project);
- handler = new BlazeUnknownRunConfigurationHandler(configuration);
- }
-
- @Test
- public void readAndWriteShouldPreserveOldContent() throws Exception {
- SAXBuilder saxBuilder = new SAXBuilder();
- XMLOutputter xmlOutputter = new XMLOutputter(Format.getCompactFormat());
-
- String inputXml =
- "<?xml version=\"1.0\"?>"
- + "<test foo=\"bar\" bar=\"baz\">"
- + " <child abc=\"def\">"
- + " <grandchild />"
- + " </child>"
- + " <child foo=\"baz\" />"
- + "</test>";
- Element element = saxBuilder.build(new StringReader(inputXml)).getRootElement();
- handler.readExternal(element);
-
- Element writeElement = new Element("test");
- handler.writeExternal(writeElement);
-
- assertThat(xmlOutputter.outputString(writeElement))
- .isEqualTo(xmlOutputter.outputString(element));
- }
-
- @Test
- public void readAndWriteShouldHandleEmptyElements() throws InvalidDataException {
- //<test />
- Element element = new Element("test");
- handler.readExternal(element);
-
- Element writeElement = new Element("test");
- handler.writeExternal(writeElement);
-
- assertThat(writeElement.getAttributes()).isEmpty();
- assertThat(writeElement.getChildren()).isEmpty();
- }
-
- @Test
- public void writeShouldPreserveNewContent() throws Exception {
- SAXBuilder saxBuilder = new SAXBuilder();
- XMLOutputter xmlOutputter = new XMLOutputter(Format.getCompactFormat());
-
- //<test />
- Element element = new Element("test");
- handler.readExternal(element);
-
- String newXml =
- "<?xml version=\"1.0\"?>"
- + "<test foo=\"bar\">"
- + " <child abc=\"def\" />"
- + " <child />"
- + "</test>";
- Element writeElement = saxBuilder.build(new StringReader(newXml)).getRootElement();
- handler.writeExternal(writeElement);
-
- Element newElement = saxBuilder.build(new StringReader(newXml)).getRootElement();
- assertThat(xmlOutputter.outputString(writeElement))
- .isEqualTo(xmlOutputter.outputString(newElement));
- }
-
- @Test
- public void writeShouldMergeAndOverwriteOldContent() throws Exception {
- SAXBuilder saxBuilder = new SAXBuilder();
- XMLOutputter xmlOutputter = new XMLOutputter(Format.getCompactFormat());
-
- String oldXml =
- "<?xml version=\"1.0\"?>"
- + "<test foo=\"old\" bar=\"old\">"
- + " <child abc=\"old\">"
- + " <grandchild />"
- + " </child>"
- + " <backup foo=\"baz\" />"
- + " <backup />"
- + "</test>";
- Element element = saxBuilder.build(new StringReader(oldXml)).getRootElement();
- handler.readExternal(element);
-
- String newXml =
- "<?xml version=\"1.0\"?>"
- + "<test foo=\"bar\">"
- + " <child abc=\"def\" />"
- + " <child />"
- + "</test>";
- Element writeElement = saxBuilder.build(new StringReader(newXml)).getRootElement();
- handler.writeExternal(writeElement);
-
- String mergedXml =
- "<?xml version=\"1.0\"?>"
- + "<test foo=\"bar\" bar=\"old\">"
- + " <child abc=\"def\" />"
- + " <child />"
- + " <backup foo=\"baz\" />"
- + " <backup />"
- + "</test>";
- Element mergedElement = saxBuilder.build(new StringReader(mergedXml)).getRootElement();
- assertThat(xmlOutputter.outputString(writeElement))
- .isEqualTo(xmlOutputter.outputString(mergedElement));
- }
-}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonStateTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonStateTest.java
new file mode 100644
index 0000000..307722c
--- /dev/null
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/state/BlazeCommandRunConfigurationCommonStateTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.run.state;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.idea.blaze.base.BlazeTestCase;
+import com.google.idea.blaze.base.command.BlazeCommandName;
+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.intellij.ide.ui.UISettings;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link BlazeCommandRunConfigurationCommonState}. */
+@RunWith(JUnit4.class)
+public class BlazeCommandRunConfigurationCommonStateTest extends BlazeTestCase {
+ private static final BlazeImportSettings DUMMY_IMPORT_SETTINGS =
+ new BlazeImportSettings("", "", "", "", "", Blaze.BuildSystem.Blaze);
+ private static final BlazeCommandName COMMAND = BlazeCommandName.fromString("command");
+
+ private BlazeCommandRunConfigurationCommonState state;
+
+ @Override
+ protected void initTest(
+ @NotNull Container applicationServices, @NotNull Container projectServices) {
+ super.initTest(applicationServices, projectServices);
+
+ applicationServices.register(UISettings.class, new UISettings());
+ projectServices.register(
+ BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
+ BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
+
+ state = new BlazeCommandRunConfigurationCommonState(Blaze.buildSystemName(project));
+ }
+
+ @Test
+ public void readAndWriteShouldMatch() throws Exception {
+ state.setCommand(COMMAND);
+ state.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
+ state.setExeFlags(ImmutableList.of("--exeFlag1"));
+ state.setBlazeBinary("/usr/bin/blaze");
+
+ Element element = new Element("test");
+ state.writeExternal(element);
+ BlazeCommandRunConfigurationCommonState readState =
+ new BlazeCommandRunConfigurationCommonState(Blaze.buildSystemName(project));
+ readState.readExternal(element);
+
+ assertThat(readState.getCommand()).isEqualTo(COMMAND);
+ assertThat(readState.getBlazeFlags()).containsExactly("--flag1", "--flag2").inOrder();
+ assertThat(readState.getExeFlags()).containsExactly("--exeFlag1");
+ assertThat(readState.getBlazeBinary()).isEqualTo("/usr/bin/blaze");
+ }
+
+ @Test
+ public void readAndWriteShouldHandleNulls() throws Exception {
+ Element element = new Element("test");
+ state.writeExternal(element);
+ BlazeCommandRunConfigurationCommonState readState =
+ new BlazeCommandRunConfigurationCommonState(Blaze.buildSystemName(project));
+ readState.readExternal(element);
+
+ assertThat(readState.getCommand()).isEqualTo(state.getCommand());
+ assertThat(readState.getBlazeFlags()).isEqualTo(state.getBlazeFlags());
+ assertThat(readState.getExeFlags()).isEqualTo(state.getExeFlags());
+ assertThat(readState.getBlazeBinary()).isEqualTo(state.getBlazeBinary());
+ }
+
+ @Test
+ public void readShouldOmitEmptyFlags() throws Exception {
+ state.setBlazeFlags(Lists.newArrayList("hi ", "", "I'm", " ", "\t", "Josh\r\n", "\n"));
+ state.setExeFlags(Lists.newArrayList("hi ", "", "I'm", " ", "\t", "Josh\r\n", "\n"));
+
+ Element element = new Element("test");
+ state.writeExternal(element);
+ BlazeCommandRunConfigurationCommonState readState =
+ new BlazeCommandRunConfigurationCommonState(Blaze.buildSystemName(project));
+ readState.readExternal(element);
+
+ assertThat(readState.getBlazeFlags()).containsExactly("hi", "I'm", "Josh").inOrder();
+ assertThat(readState.getExeFlags()).containsExactly("hi", "I'm", "Josh").inOrder();
+ }
+
+ @Test
+ public void editorApplyToAndResetFromShouldMatch() throws Exception {
+ RunConfigurationStateEditor editor = state.getEditor(project);
+
+ state.setCommand(COMMAND);
+ state.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
+ state.setExeFlags(ImmutableList.of("--exeFlag1", "--exeFlag2"));
+ state.setBlazeBinary("/usr/bin/blaze");
+
+ editor.resetEditorFrom(state);
+ BlazeCommandRunConfigurationCommonState readState =
+ new BlazeCommandRunConfigurationCommonState(Blaze.buildSystemName(project));
+ editor.applyEditorTo(readState);
+
+ assertThat(readState.getCommand()).isEqualTo(state.getCommand());
+ assertThat(readState.getBlazeFlags()).isEqualTo(state.getBlazeFlags());
+ assertThat(readState.getExeFlags()).isEqualTo(state.getExeFlags());
+ assertThat(readState.getBlazeBinary()).isEqualTo(state.getBlazeBinary());
+ }
+
+ @Test
+ public void editorApplyToAndResetFromShouldHandleNulls() throws Exception {
+ RunConfigurationStateEditor editor = state.getEditor(project);
+
+ editor.resetEditorFrom(state);
+ BlazeCommandRunConfigurationCommonState readState =
+ new BlazeCommandRunConfigurationCommonState(Blaze.buildSystemName(project));
+ editor.applyEditorTo(readState);
+
+ assertThat(readState.getCommand()).isEqualTo(state.getCommand());
+ assertThat(readState.getBlazeFlags()).isEqualTo(state.getBlazeFlags());
+ assertThat(readState.getExeFlags()).isEqualTo(state.getExeFlags());
+ assertThat(readState.getBlazeBinary()).isEqualTo(state.getBlazeBinary());
+ }
+}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/run/testmap/TestMapTest.java b/base/tests/unittests/com/google/idea/blaze/base/run/testmap/TestMapTest.java
index acb1a01..b3dfb93 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/run/testmap/TestMapTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/run/testmap/TestMapTest.java
@@ -21,11 +21,13 @@
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.ideinfo.RuleMapBuilder;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.rulemaps.ReverseDependencyMap;
import com.google.idea.blaze.base.run.testmap.TestRuleFinderImpl.TestMap;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.common.experiments.ExperimentService;
import com.google.idea.common.experiments.MockExperimentService;
import java.io.File;
@@ -39,6 +41,10 @@
public class TestMapTest extends BlazeTestCase {
private RuleMapBuilder ruleMapBuilder;
+ private final ArtifactLocationDecoder artifactLocationDecoder =
+ (ArtifactLocationDecoder)
+ artifactLocation -> new File("/", artifactLocation.getRelativePath());
+
@Override
protected void initTest(
@NotNull Container applicationServices, @NotNull Container projectServices) {
@@ -59,8 +65,8 @@
.addSource(sourceRoot("test/Test.java")))
.build();
- TestMap testMap = new TestMap(project, ruleMap);
- ImmutableMultimap<Label, Label> reverseDependencies =
+ TestMap testMap = new TestMap(project, artifactLocationDecoder, ruleMap);
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
assertThat(testMap.testTargetsForSourceFile(reverseDependencies, new File("/test/Test.java")))
.containsExactly(new Label("//test:test"));
@@ -84,8 +90,8 @@
.addSource(sourceRoot("test/Test.java")))
.build();
- TestMap testMap = new TestMap(project, ruleMap);
- ImmutableMultimap<Label, Label> reverseDependencies =
+ TestMap testMap = new TestMap(project, artifactLocationDecoder, ruleMap);
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
assertThat(testMap.testTargetsForSourceFile(reverseDependencies, new File("/test/Test.java")))
.containsExactly(new Label("//test:test"));
@@ -115,8 +121,8 @@
.addSource(sourceRoot("test/Test.java")))
.build();
- TestMap testMap = new TestMap(project, ruleMap);
- ImmutableMultimap<Label, Label> reverseDependencies =
+ TestMap testMap = new TestMap(project, artifactLocationDecoder, ruleMap);
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
assertThat(testMap.testTargetsForSourceFile(reverseDependencies, new File("/test/Test.java")))
.containsExactly(new Label("//test:test"), new Label("//test:test2"));
@@ -152,8 +158,8 @@
.addDependency("//test:lib"))
.build();
- TestMap testMap = new TestMap(project, ruleMap);
- ImmutableMultimap<Label, Label> reverseDependencies =
+ TestMap testMap = new TestMap(project, artifactLocationDecoder, ruleMap);
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
assertThat(testMap.testTargetsForSourceFile(reverseDependencies, new File("/test/Test.java")))
.containsExactly(new Label("//test:test"), new Label("//test:test2"))
@@ -190,8 +196,8 @@
.addSource(sourceRoot("test/Test.java")))
.build();
- TestMap testMap = new TestMap(project, ruleMap);
- ImmutableMultimap<Label, Label> reverseDependencies =
+ TestMap testMap = new TestMap(project, artifactLocationDecoder, ruleMap);
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
assertThat(testMap.testTargetsForSourceFile(reverseDependencies, new File("/test/Test.java")))
.containsExactly(new Label("//test:test"), new Label("//test:test2"));
@@ -222,8 +228,8 @@
.addSource(sourceRoot("test/Test.java")))
.build();
- TestMap testMap = new TestMap(project, ruleMap);
- ImmutableMultimap<Label, Label> reverseDependencies =
+ TestMap testMap = new TestMap(project, artifactLocationDecoder, ruleMap);
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies =
ReverseDependencyMap.createRdepsMap(ruleMap);
assertThat(testMap.testTargetsForSourceFile(reverseDependencies, new File("/test/Test.java")))
.containsExactly(new Label("//test:test"));
@@ -231,7 +237,6 @@
private ArtifactLocation sourceRoot(String relativePath) {
return ArtifactLocation.builder()
- .setRootPath("/")
.setRelativePath(relativePath)
.setIsSource(true)
.build();
diff --git a/base/tests/unittests/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImplTest.java b/base/tests/unittests/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImplTest.java
index 24a6200..7d005db 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImplTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/sync/aspects/BlazeIdeInterfaceAspectsImplTest.java
@@ -15,23 +15,17 @@
*/
package com.google.idea.blaze.base.sync.aspects;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.TestUtils;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.io.FileAttributeProvider;
-import com.google.idea.blaze.base.model.RuleMap;
-import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
-import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.model.primitives.WorkspaceType;
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.WorkspacePathResolverImpl;
import com.google.idea.common.experiments.ExperimentService;
import com.google.idea.common.experiments.MockExperimentService;
import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo;
@@ -46,16 +40,6 @@
public class BlazeIdeInterfaceAspectsImplTest extends BlazeTestCase {
private static final File DUMMY_ROOT = new File("/");
- private static final WorkspaceRoot WORKSPACE_ROOT = new WorkspaceRoot(DUMMY_ROOT);
- private static final BlazeRoots BLAZE_ROOTS =
- new BlazeRoots(
- DUMMY_ROOT,
- ImmutableList.of(DUMMY_ROOT),
- new ExecutionRootPath("out/crosstool/bin"),
- new ExecutionRootPath("out/crosstool/gen"));
- private static final ArtifactLocationDecoder DUMMY_DECODER =
- new ArtifactLocationDecoder(
- BLAZE_ROOTS, new WorkspacePathResolverImpl(WORKSPACE_ROOT, BLAZE_ROOTS));
@Override
protected void initTest(
@@ -96,14 +80,17 @@
new WorkspaceLanguageSettings(
WorkspaceType.ANDROID, ImmutableSet.of(LanguageClass.ANDROID));
RuleIdeInfo ruleIdeInfo =
- IdeInfoFromProtobuf.makeRuleIdeInfo(workspaceLanguageSettings, DUMMY_DECODER, ideProto);
+ IdeInfoFromProtobuf.makeRuleIdeInfo(workspaceLanguageSettings, ideProto);
TestUtils.assertIsSerializable(ruleIdeInfo);
}
@Test
public void testBlazeStateIsSerializable() {
BlazeIdeInterfaceAspectsImpl.State state = new BlazeIdeInterfaceAspectsImpl.State();
- state.fileToLabel = ImmutableMap.of(new File("fileName"), new Label("//java/com/test:test"));
+ state.fileToRuleMapKey =
+ ImmutableMap.of(
+ new File("fileName"),
+ RuleIdeInfo.builder().setLabel(new Label("//test:test")).build().key);
state.fileState = ImmutableMap.of();
state.ruleMap =
new RuleMap(ImmutableMap.of()); // Tested separately in testRuleIdeInfoIsSerializable
@@ -117,8 +104,6 @@
static AndroidStudioIdeInfo.ArtifactLocation artifactLocation(
String rootPath, String relativePath) {
- return AndroidStudioIdeInfo.ArtifactLocation.newBuilder()
- .setRelativePath(relativePath)
- .build();
+ return AndroidStudioIdeInfo.ArtifactLocation.newBuilder().setRelativePath(relativePath).build();
}
}
diff --git a/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderTest.java b/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderTest.java
index c6ea540..02849cd 100644
--- a/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderTest.java
+++ b/base/tests/unittests/com/google/idea/blaze/base/sync/workspace/ArtifactLocationDecoderTest.java
@@ -25,8 +25,6 @@
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
-import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo;
-import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.PackageManifestOuterClass;
import java.io.File;
import java.util.List;
import java.util.Set;
@@ -39,25 +37,8 @@
@RunWith(JUnit4.class)
public class ArtifactLocationDecoderTest extends BlazeTestCase {
- private static final WorkspaceRoot WORKSPACE_ROOT = new WorkspaceRoot(new File("/path/to/root"));
private static final String EXECUTION_ROOT = "/path/to/_blaze_user/1234bf129e/root";
- private static final BlazeRoots BLAZE_GIT5_ROOTS =
- new BlazeRoots(
- new File(EXECUTION_ROOT),
- ImmutableList.of(
- WORKSPACE_ROOT.directory(),
- new File(WORKSPACE_ROOT.directory().getParentFile(), "READONLY/root")),
- new ExecutionRootPath("root/blaze-out/crosstool/bin"),
- new ExecutionRootPath("root/blaze-out/crosstool/genfiles"));
-
- private static final BlazeRoots BLAZE_CITC_ROOTS =
- new BlazeRoots(
- new File(EXECUTION_ROOT),
- ImmutableList.of(WORKSPACE_ROOT.directory()),
- new ExecutionRootPath("root/blaze-out/crosstool/bin"),
- new ExecutionRootPath("root/blaze-out/crosstool/genfiles"));
-
static class MockFileAttributeProvider extends FileAttributeProvider {
final Set<File> files = Sets.newHashSet();
@@ -86,9 +67,9 @@
public void testManualPackagePaths() throws Exception {
List<File> packagePaths =
ImmutableList.of(
- WORKSPACE_ROOT.directory(),
- new File(WORKSPACE_ROOT.directory().getParentFile(), "READONLY/root"),
- new File(WORKSPACE_ROOT.directory().getParentFile(), "CUSTOM/root"));
+ new File("/path/to"),
+ new File("/path/to/READONLY/root"),
+ new File("/path/to/CUSTOM/root"));
BlazeRoots blazeRoots =
new BlazeRoots(
@@ -98,117 +79,55 @@
new ExecutionRootPath("root/blaze-out/crosstool/genfiles"));
fileChecker.addFiles(
- new File(packagePaths.get(0), "com/google/Bla.java"),
- new File(packagePaths.get(1), "com/google/Foo.java"),
- new File(packagePaths.get(2), "com/other/Test.java"));
+ new File("/path/to/com/google/Bla.java"),
+ new File("/path/to/READONLY/root/com/google/Foo.java"),
+ new File("/path/to/CUSTOM/root/com/other/Test.java"));
ArtifactLocationDecoder decoder =
- new ArtifactLocationDecoder(
- blazeRoots, new WorkspacePathResolverImpl(WORKSPACE_ROOT, blazeRoots));
+ new ArtifactLocationDecoderImpl(
+ blazeRoots,
+ new WorkspacePathResolverImpl(
+ new WorkspaceRoot(new File("/path/to/root")), blazeRoots));
- ArtifactLocationBuilder builder =
- new ArtifactLocationBuilder().setRelativePath("com/google/Bla.java").setIsSource(true);
+ ArtifactLocation blah =
+ ArtifactLocation.builder().setRelativePath("com/google/Bla.java").setIsSource(true).build();
+ assertThat(decoder.decode(blah).getPath()).isEqualTo("/path/to/com/google/Bla.java");
- assertThat(decoder.decode(builder.buildIdeInfoArtifact()).getRootPath())
- .isEqualTo(packagePaths.get(0).toString());
+ ArtifactLocation foo =
+ ArtifactLocation.builder().setRelativePath("com/google/Foo.java").setIsSource(true).build();
+ assertThat(decoder.decode(foo).getPath())
+ .isEqualTo("/path/to/READONLY/root/com/google/Foo.java");
- builder.setRelativePath("com/google/Foo.java");
+ ArtifactLocation test =
+ ArtifactLocation.builder().setRelativePath("com/other/Test.java").setIsSource(true).build();
+ assertThat(decoder.decode(test).getPath())
+ .isEqualTo("/path/to/CUSTOM/root/com/other/Test.java");
- assertThat(decoder.decode(builder.buildIdeInfoArtifact()).getRootPath())
- .isEqualTo(packagePaths.get(1).toString());
-
- builder.setRelativePath("com/other/Test.java");
-
- assertThat(decoder.decode(builder.buildIdeInfoArtifact()).getRootPath())
- .isEqualTo(packagePaths.get(2).toString());
-
- builder.setRelativePath("third_party/other/Temp.java");
-
- assertThat(decoder.decode(builder.buildIdeInfoArtifact())).isNull();
+ ArtifactLocation.Builder temp =
+ ArtifactLocation.builder().setRelativePath("third_party/other/Temp.java").setIsSource(true);
+ assertThat(decoder.decode(temp.build()).getPath())
+ .isEqualTo("/path/to/third_party/other/Temp.java");
}
@Test
- public void testDerivedArtifact() throws Exception {
- ArtifactLocationBuilder builder =
- new ArtifactLocationBuilder()
+ public void testGeneratedArtifact() throws Exception {
+ ArtifactLocation artifactLocation =
+ ArtifactLocation.builder()
.setRootExecutionPathFragment("/blaze-out/bin")
.setRelativePath("com/google/Bla.java")
- .setIsSource(false);
-
- ArtifactLocationDecoder decoder = new ArtifactLocationDecoder(BLAZE_CITC_ROOTS, null);
-
- ArtifactLocation parsed = decoder.decode(builder.buildIdeInfoArtifact());
-
- assertThat(parsed).isEqualTo(decoder.decode(builder.buildManifestArtifact()));
-
- assertThat(parsed)
- .isEqualTo(
- ArtifactLocation.builder()
- .setRootPath(EXECUTION_ROOT + "/blaze-out/bin")
- .setRootExecutionPathFragment("/blaze-out/bin")
- .setRelativePath("com/google/Bla.java")
- .setIsSource(false)
- .build());
- }
-
- @Test
- public void testSourceArtifactAllVersions() throws Exception {
- ArtifactLocationBuilder builder =
- new ArtifactLocationBuilder().setRelativePath("com/google/Bla.java").setIsSource(true);
+ .setIsSource(false)
+ .build();
ArtifactLocationDecoder decoder =
- new ArtifactLocationDecoder(
- BLAZE_CITC_ROOTS, new WorkspacePathResolverImpl(WORKSPACE_ROOT, BLAZE_CITC_ROOTS));
+ new ArtifactLocationDecoderImpl(
+ new BlazeRoots(
+ new File(EXECUTION_ROOT),
+ ImmutableList.of(new File("/path/to/root")),
+ new ExecutionRootPath("root/blaze-out/crosstool/bin"),
+ new ExecutionRootPath("root/blaze-out/crosstool/genfiles")),
+ null);
- ArtifactLocation parsed = decoder.decode(builder.buildIdeInfoArtifact());
-
- assertThat(parsed).isEqualTo(decoder.decode(builder.buildManifestArtifact()));
-
- assertThat(parsed)
- .isEqualTo(
- ArtifactLocation.builder()
- .setRootPath(WORKSPACE_ROOT.toString())
- .setRelativePath("com/google/Bla.java")
- .setIsSource(true)
- .build());
- }
-
- static class ArtifactLocationBuilder {
- String rootExecutionPathFragment = "";
- String relativePath;
- boolean isSource;
-
- ArtifactLocationBuilder setRootExecutionPathFragment(String rootExecutionPathFragment) {
- this.rootExecutionPathFragment = rootExecutionPathFragment;
- return this;
- }
-
- ArtifactLocationBuilder setRelativePath(String relativePath) {
- this.relativePath = relativePath;
- return this;
- }
-
- ArtifactLocationBuilder setIsSource(boolean isSource) {
- this.isSource = isSource;
- return this;
- }
-
- AndroidStudioIdeInfo.ArtifactLocation buildIdeInfoArtifact() {
- AndroidStudioIdeInfo.ArtifactLocation.Builder builder =
- AndroidStudioIdeInfo.ArtifactLocation.newBuilder()
- .setIsSource(isSource)
- .setRelativePath(relativePath);
- builder.setRootExecutionPathFragment(rootExecutionPathFragment);
- return builder.build();
- }
-
- PackageManifestOuterClass.ArtifactLocation buildManifestArtifact() {
- PackageManifestOuterClass.ArtifactLocation.Builder builder =
- PackageManifestOuterClass.ArtifactLocation.newBuilder()
- .setIsSource(isSource)
- .setRelativePath(relativePath);
- builder.setRootExecutionPathFragment(rootExecutionPathFragment);
- return builder.build();
- }
+ assertThat(decoder.decode(artifactLocation).getPath())
+ .isEqualTo(EXECUTION_ROOT + "/blaze-out/bin/com/google/Bla.java");
}
}
diff --git a/base/tests/utils/integration/com/google/idea/blaze/base/BlazeIntegrationTestCase.java b/base/tests/utils/integration/com/google/idea/blaze/base/BlazeIntegrationTestCase.java
index 06596be..98dc27d 100644
--- a/base/tests/utils/integration/com/google/idea/blaze/base/BlazeIntegrationTestCase.java
+++ b/base/tests/utils/integration/com/google/idea/blaze/base/BlazeIntegrationTestCase.java
@@ -30,24 +30,23 @@
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.testing.EdtRule;
+import com.google.idea.testing.IntellijTestSetupRule;
+import com.google.idea.testing.ServiceHelper;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementPresentation;
-import com.intellij.ide.plugins.PluginManagerCore;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
-import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.ExtensionPointName;
-import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
-import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.ex.temp.TempFileSystem;
@@ -82,37 +81,25 @@
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
-import org.picocontainer.MutablePicoContainer;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TestRule;
-/** Base test class for blaze integration tests. */
-public abstract class BlazeIntegrationTestCase extends UsefulTestCase {
+/** Base test class for blaze integration tests. {@link UsefulTestCase} */
+public abstract class BlazeIntegrationTestCase {
private static final LightProjectDescriptor projectDescriptor =
LightCodeInsightFixtureTestCase.JAVA_8;
- private static boolean isRunThroughBlaze() {
- return System.getenv("JAVA_RUNFILES") != null;
- }
+ @Rule public final IntellijTestSetupRule setupRule = new IntellijTestSetupRule();
+ @Rule public final TestRule testRunWrapper = runTestsOnEdt() ? new EdtRule() : null;
protected CodeInsightTestFixture testFixture;
protected WorkspaceRoot workspaceRoot;
- private String oldPluginPathProperty;
- @Override
- protected final void setUp() throws Exception {
- if (!isRunThroughBlaze()) {
- // If running directly through the IDE, don't try to load plugins from the sandbox environment
- // Instead we'll rely on the slightly more hermetic module classpath
- oldPluginPathProperty = System.getProperty(PathManager.PROPERTY_PLUGINS_PATH);
- System.setProperty(PathManager.PROPERTY_PLUGINS_PATH, "/dev/null");
- }
-
- // Some plugins have a since-build and until-build restriction, so we need
- // to update the build number here
- PluginManagerCore.BUILD_NUMBER = "162.1447.26";
-
- super.setUp();
-
+ @Before
+ public final void setUp() throws Exception {
IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory();
TestFixtureBuilder<IdeaProjectTestFixture> fixtureBuilder =
factory.createLightFixtureBuilder(projectDescriptor);
@@ -147,8 +134,10 @@
}
return vf.getInputStream();
});
+ }
- doSetup();
+ protected Disposable getTestRootDisposable() {
+ return setupRule.testRootDisposable;
}
/** Override to run tests with bazel specified as the project's build system. */
@@ -156,23 +145,16 @@
return BuildSystem.Blaze;
}
- protected void doSetup() throws Exception {}
-
- @Override
- protected final void tearDown() throws Exception {
- if (oldPluginPathProperty != null) {
- System.setProperty(PathManager.PROPERTY_PLUGINS_PATH, oldPluginPathProperty);
- } else {
- System.clearProperty(PathManager.PROPERTY_PLUGINS_PATH);
- }
- testFixture.tearDown();
- testFixture = null;
- super.tearDown();
- clearFields(this);
- doTearDown();
+ /** Override to run tests off the EDT. */
+ protected boolean runTestsOnEdt() {
+ return true;
}
- protected void doTearDown() throws Exception {}
+ @After
+ public final void tearDown() throws Exception {
+ testFixture.tearDown();
+ testFixture = null;
+ }
protected void setBlazeImportSettings(BlazeImportSettings importSettings) {
BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(importSettings);
@@ -435,36 +417,16 @@
}
protected <T> void registerApplicationService(Class<T> key, T implementation) {
- registerComponentInstance(
- (MutablePicoContainer) ApplicationManager.getApplication().getPicoContainer(),
- key,
- implementation);
+ ServiceHelper.registerApplicationService(key, implementation, getTestRootDisposable());
}
protected <T> void registerProjectService(Class<T> key, T implementation) {
- registerComponentInstance(
- (MutablePicoContainer) getProject().getPicoContainer(), key, implementation);
- }
-
- protected <T> void registerComponentInstance(
- MutablePicoContainer container, Class<T> key, T implementation) {
- Object old = container.getComponentInstance(key);
- container.unregisterComponent(key.getName());
- container.registerComponentInstance(key.getName(), implementation);
- Disposer.register(
- getTestRootDisposable(),
- () -> {
- container.unregisterComponent(key.getName());
- if (old != null) {
- container.registerComponentInstance(key.getName(), old);
- }
- });
+ ServiceHelper.registerProjectService(
+ getProject(), key, implementation, getTestRootDisposable());
}
protected <T> void registerExtension(ExtensionPointName<T> name, T instance) {
- ExtensionPoint<T> ep = Extensions.getRootArea().getExtensionPoint(name);
- ep.registerExtension(instance);
- Disposer.register(getTestRootDisposable(), () -> ep.unregisterExtension(instance));
+ ServiceHelper.registerExtension(name, instance, getTestRootDisposable());
}
/** Redirects file system checks via the TempFileSystem used for these tests. */
diff --git a/base/tests/utils/integration/com/google/idea/blaze/base/lang/buildfile/BuildFileIntegrationTestCase.java b/base/tests/utils/integration/com/google/idea/blaze/base/lang/buildfile/BuildFileIntegrationTestCase.java
index fa91385..0dcea85 100644
--- a/base/tests/utils/integration/com/google/idea/blaze/base/lang/buildfile/BuildFileIntegrationTestCase.java
+++ b/base/tests/utils/integration/com/google/idea/blaze/base/lang/buildfile/BuildFileIntegrationTestCase.java
@@ -20,23 +20,27 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.base.BlazeIntegrationTestCase;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
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.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoderImpl;
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.base.sync.workspace.WorkspacePathResolverImpl;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiFile;
+import org.junit.Before;
/** BUILD file specific integration test base */
public abstract class BuildFileIntegrationTestCase extends BlazeIntegrationTestCase {
- @Override
- protected void doSetup() {
+ @Before
+ public final void doSetup() {
mockBlazeProjectDataManager(getMockBlazeProjectData());
}
@@ -67,12 +71,17 @@
ImmutableList.of(workspaceRoot.directory()),
new ExecutionRootPath("out/crosstool/bin"),
new ExecutionRootPath("out/crosstool/gen"));
+ WorkspacePathResolver workspacePathResolver =
+ new WorkspacePathResolverImpl(workspaceRoot, fakeRoots);
+ ArtifactLocationDecoder artifactLocationDecoder =
+ new ArtifactLocationDecoderImpl(fakeRoots, workspacePathResolver);
return new BlazeProjectData(
0,
new RuleMap(ImmutableMap.of()),
fakeRoots,
new WorkingSet(ImmutableList.of(), ImmutableList.of(), ImmutableList.of()),
- new WorkspacePathResolverImpl(workspaceRoot, fakeRoots),
+ workspacePathResolver,
+ artifactLocationDecoder,
null,
null,
null,
diff --git a/base/tests/utils/integration/com/google/idea/blaze/base/sync/BlazeSyncIntegrationTestCase.java b/base/tests/utils/integration/com/google/idea/blaze/base/sync/BlazeSyncIntegrationTestCase.java
index 180e1cc..fd78f8c 100644
--- a/base/tests/utils/integration/com/google/idea/blaze/base/sync/BlazeSyncIntegrationTestCase.java
+++ b/base/tests/utils/integration/com/google/idea/blaze/base/sync/BlazeSyncIntegrationTestCase.java
@@ -28,8 +28,8 @@
import com.google.idea.blaze.base.BlazeIntegrationTestCase;
import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.io.WorkspaceScanner;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
import com.google.idea.blaze.base.model.primitives.TargetExpression;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
@@ -64,6 +64,8 @@
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
+import org.junit.After;
+import org.junit.Before;
/** Sets up mocks required for integration tests of the blaze sync process. */
public abstract class BlazeSyncIntegrationTestCase extends BlazeIntegrationTestCase {
@@ -89,10 +91,11 @@
protected ErrorCollector errorCollector;
protected BlazeContext context;
- @Override
- protected void doSetup() throws IOException {
+ @Before
+ public void doSetup() throws Exception {
// Set up a workspace root outside of the tracked temp file system.
tempDirectoryHandler = new LightTempDirTestFixtureImpl();
+ tempDirectoryHandler.setUp();
tempDirectory = tempDirectoryHandler.getFile("");
workspaceRoot = new WorkspaceRoot(new File(tempDirectory.getPath()));
setBlazeImportSettings(
@@ -125,7 +128,7 @@
// don't commit module changes,
// but make sure they're properly disposed when the test is finished
for (ModifiableRootModel model : modifiableModels) {
- Disposer.register(myTestRootDisposable, model::dispose);
+ Disposer.register(getTestRootDisposable(), model::dispose);
}
}
};
@@ -150,12 +153,11 @@
workspaceRoot.toString()));
}
- @Override
- protected void doTearDown() throws Exception {
+ @After
+ public final void doTearDown() throws Exception {
if (tempDirectoryHandler != null) {
tempDirectoryHandler.tearDown();
}
- super.doTearDown();
}
protected VirtualFile createWorkspaceFile(String relativePath, @Nullable String... contents) {
@@ -173,7 +175,6 @@
protected ArtifactLocation sourceRoot(String relativePath) {
return ArtifactLocation.builder()
- .setRootPath(workspaceRoot.toString())
.setRelativePath(relativePath)
.setIsSource(true)
.build();
diff --git a/base/tests/utils/unit/com/google/idea/blaze/base/ideinfo/RuleMapBuilder.java b/base/tests/utils/unit/com/google/idea/blaze/base/ideinfo/RuleMapBuilder.java
index 2586377..2b82cd9 100644
--- a/base/tests/utils/unit/com/google/idea/blaze/base/ideinfo/RuleMapBuilder.java
+++ b/base/tests/utils/unit/com/google/idea/blaze/base/ideinfo/RuleMapBuilder.java
@@ -17,8 +17,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
-import com.google.idea.blaze.base.model.RuleMap;
-import com.google.idea.blaze.base.model.primitives.Label;
import java.util.List;
import org.jetbrains.annotations.NotNull;
@@ -43,9 +41,10 @@
@NotNull
public RuleMap build() {
- ImmutableMap.Builder<Label, RuleIdeInfo> ruleMap = ImmutableMap.builder();
+ ImmutableMap.Builder<RuleKey, RuleIdeInfo> ruleMap = ImmutableMap.builder();
for (RuleIdeInfo rule : rules) {
- ruleMap.put(rule.label, rule);
+ RuleKey key = rule.key;
+ ruleMap.put(key, rule);
}
return new RuleMap(ruleMap.build());
}
diff --git a/base/tests/utils/unit/com/google/idea/blaze/base/run/MockBlazeCommandRunConfigurationHandlerProvider.java b/base/tests/utils/unit/com/google/idea/blaze/base/run/MockBlazeCommandRunConfigurationHandlerProvider.java
index 92ab14e..4f30237 100644
--- a/base/tests/utils/unit/com/google/idea/blaze/base/run/MockBlazeCommandRunConfigurationHandlerProvider.java
+++ b/base/tests/utils/unit/com/google/idea/blaze/base/run/MockBlazeCommandRunConfigurationHandlerProvider.java
@@ -17,15 +17,17 @@
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerEditor;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerProvider;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
+import com.google.idea.blaze.base.run.state.RunConfigurationState;
+import com.google.idea.blaze.base.run.state.RunConfigurationStateEditor;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.project.Project;
import javax.annotation.Nullable;
import javax.swing.Icon;
import javax.swing.JComponent;
@@ -49,23 +51,11 @@
return "MockBlazeCommandRunConfigurationHandlerProvider";
}
- /** A mock {@link BlazeCommandRunConfigurationHandler}. */
- private static class MockBlazeCommandRunConfigurationHandler
- implements BlazeCommandRunConfigurationHandler {
-
- final BlazeCommandRunConfiguration configuration;
-
- MockBlazeCommandRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
- this.configuration = configuration;
- }
+ /** A mock {@link RunConfigurationState}. */
+ private static class MockRunConfigurationState implements RunConfigurationState {
@Override
- public void checkConfiguration() throws RuntimeConfigurationException {
- // Don't throw anything.
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
+ public void readExternal(Element element) {
// Don't read anything.
}
@@ -75,13 +65,32 @@
}
@Override
- public BlazeCommandRunConfigurationHandler cloneFor(
- BlazeCommandRunConfiguration configuration) {
- return new MockBlazeCommandRunConfigurationHandler(configuration);
+ public RunConfigurationStateEditor getEditor(Project project) {
+ return new RunConfigurationStateEditor() {
+ @Override
+ public void resetEditorFrom(RunConfigurationState state) {
+ // Do nothing.
+ }
+
+ @Override
+ public void applyEditorTo(RunConfigurationState state) {
+ // Do nothing.
+ }
+
+ @Override
+ public JComponent createComponent() {
+ return null;
+ }
+ };
}
+ }
+
+ /** A mock {@link MockBlazeCommandRunConfigurationRunner}. */
+ private static class MockBlazeCommandRunConfigurationRunner
+ implements BlazeCommandRunConfigurationRunner {
@Override
- public RunProfileState getState(Executor executor, ExecutionEnvironment environment)
+ public RunProfileState getRunProfileState(Executor executor, ExecutionEnvironment environment)
throws ExecutionException {
return null;
}
@@ -90,16 +99,40 @@
public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
return true;
}
+ }
- @Nullable
- @Override
- public String suggestedName() {
- return null;
+ /** A mock {@link BlazeCommandRunConfigurationHandler}. */
+ private static class MockBlazeCommandRunConfigurationHandler
+ implements BlazeCommandRunConfigurationHandler {
+
+ final BlazeCommandRunConfiguration configuration;
+ final MockRunConfigurationState state;
+
+ MockBlazeCommandRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
+ this.configuration = configuration;
+ this.state = new MockRunConfigurationState();
}
@Override
- public boolean isGeneratedName(boolean hasGeneratedFlag) {
- return hasGeneratedFlag;
+ public MockRunConfigurationState getState() {
+ return state;
+ }
+
+ @Override
+ public BlazeCommandRunConfigurationRunner createRunner(
+ Executor executor, ExecutionEnvironment environment) {
+ return new MockBlazeCommandRunConfigurationRunner();
+ }
+
+ @Override
+ public void checkConfiguration() throws RuntimeConfigurationException {
+ // Don't throw anything.
+ }
+
+ @Nullable
+ @Override
+ public String suggestedName(BlazeCommandRunConfiguration configuration) {
+ return null;
}
@Nullable
@@ -118,26 +151,5 @@
public Icon getExecutorIcon(RunConfiguration configuration, Executor executor) {
return null;
}
-
- @Override
- public BlazeCommandRunConfigurationHandlerEditor getHandlerEditor() {
- return new BlazeCommandRunConfigurationHandlerEditor() {
- @Override
- public void resetEditorFrom(BlazeCommandRunConfigurationHandler handler) {
- // Do nothing.
- }
-
- @Override
- public void applyEditorTo(BlazeCommandRunConfigurationHandler handler) {
- // Do nothing.
- }
-
- @Nullable
- @Override
- public JComponent createEditor() {
- return null;
- }
- };
- }
}
}
diff --git a/build_defs/build_defs.bzl b/build_defs/build_defs.bzl
index 974b857..d8c9613 100644
--- a/build_defs/build_defs.bzl
+++ b/build_defs/build_defs.bzl
@@ -5,6 +5,7 @@
"merged_plugin_xml_impl",
"stamped_plugin_xml_impl",
"product_build_txt_impl",
+ "api_version_txt_impl",
"intellij_plugin_impl",
"plugin_bundle_impl")
@@ -25,6 +26,8 @@
include_product_code_in_stamp=False,
version_file=None,
changelog_file=None,
+ description_file=None,
+ vendor_file=None,
**kwargs):
"""Stamps a plugin xml file with the IJ build number.
@@ -39,12 +42,16 @@
is included in since-build and until-build.
version_file: A file with the version number to be included.
changelog_file: A file with changelog to be included.
+ description_file: A file containing a plugin description to be included.
+ vendor_file: A file containing the vendor info to be included.
**kwargs: Any additional arguments to pass to the final target.
"""
+ api_version_txt(
+ name = name + "_api_version",
+ )
stamped_plugin_xml_impl(
name = name,
- application_info_jar = "//intellij_platform_sdk:application_info_jar",
- application_info_name = "//intellij_platform_sdk:application_info_name",
+ api_version_txt = name + "_api_version",
plugin_id = plugin_id,
plugin_name = plugin_name,
stamp_tool = "//build_defs/shared:stamp_plugin_xml",
@@ -54,6 +61,8 @@
include_product_code_in_stamp = include_product_code_in_stamp,
version_file = version_file,
changelog_file = changelog_file,
+ description_file = description_file,
+ vendor_file = vendor_file,
**kwargs)
def product_build_txt(name, **kwargs):
@@ -65,6 +74,14 @@
product_build_txt_tool = "//build_defs/shared:product_build_txt",
**kwargs)
+def api_version_txt(name, **kwargs):
+ """Produces an api_version.txt file with the api version, including the product code."""
+ api_version_txt_impl(
+ name = name,
+ application_info_jar = "//intellij_platform_sdk:application_info_jar",
+ application_info_name = "//intellij_platform_sdk:application_info_name",
+ api_version_txt_tool = "//build_defs/shared:api_version_txt",
+ **kwargs)
def intellij_plugin(name, plugin_xml, deps, meta_inf_files=[], **kwargs):
"""Creates an intellij plugin from the given deps and plugin.xml."""
diff --git a/build_defs/shared/BUILD b/build_defs/shared/BUILD
index bb4815c..3c8b0b3 100644
--- a/build_defs/shared/BUILD
+++ b/build_defs/shared/BUILD
@@ -20,3 +20,8 @@
name = "product_build_txt",
srcs = ["product_build_txt.py"],
)
+
+py_binary(
+ name = "api_version_txt",
+ srcs = ["api_version_txt.py"],
+)
diff --git a/build_defs/shared/api_version_txt.py b/build_defs/shared/api_version_txt.py
new file mode 100755
index 0000000..a1250c5
--- /dev/null
+++ b/build_defs/shared/api_version_txt.py
@@ -0,0 +1,74 @@
+"""Produces a api_version.txt file with the plugin API version.
+"""
+
+import argparse
+import re
+from xml.dom.minidom import parseString
+import zipfile
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument(
+ "--application_info_jar",
+ help="The jar file containing the application info xml",
+ required=True,)
+parser.add_argument(
+ "--application_info_name",
+ help="A .txt file containing the application info xml name",
+ required=True,)
+
+
+def _parse_build_number(build_number):
+ """Parses the build number.
+
+ Args:
+ build_number: The build number as text.
+ Returns:
+ build_number, build_number_without_product_code.
+ Raises:
+ ValueError: if the build number is invalid.
+ """
+ match = re.match(r"^([A-Z]+-)?([0-9]+)((\.[0-9]+)*)", build_number)
+ if match is None:
+ raise ValueError("Invalid build number: " + build_number)
+
+ return match.group(1) + match.group(2) + match.group(3)
+
+
+def main():
+
+ args = parser.parse_args()
+
+ with open(args.application_info_name) as f:
+ application_info_name = f.read().strip()
+
+ with zipfile.ZipFile(args.application_info_jar, "r") as zf:
+ try:
+ data = zf.read(application_info_name)
+ except:
+ raise ValueError("Could not read application info file: " +
+ application_info_name)
+ component = parseString(data)
+
+ build_elements = component.getElementsByTagName("build")
+ if not build_elements:
+ raise ValueError("Could not find <build> element.")
+ if len(build_elements) > 1:
+ raise ValueError("Ambiguous <build> element.")
+ build_element = build_elements[0]
+
+ attrs = build_element.attributes
+ if attrs.has_key("apiVersion"):
+ api_version_attr = attrs.get("apiVersion")
+ else:
+ api_version_attr = attrs.get("number")
+
+ if not api_version_attr:
+ raise ValueError("Could not find api version in application info")
+
+ api_version = _parse_build_number(api_version_attr.value)
+ print api_version
+
+
+if __name__ == "__main__":
+ main()
diff --git a/build_defs/shared/build_defs.bzl b/build_defs/shared/build_defs.bzl
index 5c282ee..5726ed0 100644
--- a/build_defs/shared/build_defs.bzl
+++ b/build_defs/shared/build_defs.bzl
@@ -18,8 +18,7 @@
def stamped_plugin_xml_impl(name,
plugin_xml,
- application_info_jar,
- application_info_name,
+ api_version_txt,
stamp_tool,
plugin_id = None,
plugin_name = None,
@@ -28,14 +27,15 @@
include_product_code_in_stamp=False,
version_file=None,
changelog_file=None,
+ description_file=None,
+ vendor_file=None,
**kwargs):
"""Stamps a plugin xml file with the IJ build number.
Args:
name: name of this target
plugin_xml: target plugin_xml to stamp
- application_info_jar: the jar containing the application info
- application_info_name: a file with the name of the application info
+ api_version_txt: the file containing the api version
stamp_tool: the tool to use to stamp the version
plugin_id: the plugin ID to stamp
plugin_name: the plugin name to stamp
@@ -45,18 +45,19 @@
is included in since-build and until-build.
version_file: A file with the version number to be included.
changelog_file: A file with the changelog to be included.
+ description_file: A file containing a plugin description to be included.
+ vendor_file: A file containing the vendor info to be included.
**kwargs: Any additional arguments to pass to the final target.
"""
args = [
"./$(location {stamp_tool})",
"--plugin_xml=$(location {plugin_xml})",
- "--application_info_jar=$(location {application_info_jar})",
- "--application_info_name=$(location {application_info_name})",
+ "--api_version_txt=$(location {api_version_txt})",
"{stamp_since_build}",
"{stamp_until_build}",
"{include_product_code_in_stamp}",
]
- srcs = [plugin_xml, application_info_jar, application_info_name]
+ srcs = [plugin_xml, api_version_txt]
if plugin_id:
args.append("--plugin_id=%s" % plugin_id)
@@ -72,10 +73,17 @@
args.append("--changelog_file=$(location {changelog_file})")
srcs.append(changelog_file)
+ if description_file:
+ args.append("--description_file=$(location {description_file})")
+ srcs.append(description_file)
+
+ if vendor_file:
+ args.append("--vendor_file=$(location {vendor_file})")
+ srcs.append(vendor_file)
+
cmd = " ".join(args).format(
plugin_xml=plugin_xml,
- application_info_jar=application_info_jar,
- application_info_name=application_info_name,
+ api_version_txt=api_version_txt,
stamp_tool=stamp_tool,
stamp_since_build=_optstr("stamp_since_build",
stamp_since_build),
@@ -86,6 +94,8 @@
include_product_code_in_stamp),
version_file=version_file,
changelog_file=changelog_file,
+ description_file=description_file,
+ vendor_file=vendor_file,
) + "> $@"
native.genrule(
@@ -128,6 +138,38 @@
tools = [product_build_txt_tool],
**kwargs)
+def api_version_txt_impl(name,
+ api_version_txt_tool,
+ application_info_jar,
+ application_info_name,
+ **kwargs):
+ """Produces an api_version.txt file with the api version, including the product code.
+
+ Args:
+ name: name of this target
+ api_version_txt_tool: the api version tool
+ application_info_jar: the jar containing the application info
+ application_info_name: a file with the name of the application info
+ **kwargs: Any additional arguments to pass to the final target.
+ """
+ args = [
+ "./$(location {api_version_txt_tool})",
+ "--application_info_jar=$(location {application_info_jar})",
+ "--application_info_name=$(location {application_info_name})",
+ ]
+ cmd = " ".join(args).format(
+ application_info_jar=application_info_jar,
+ application_info_name=application_info_name,
+ api_version_txt_tool=api_version_txt_tool,
+ ) + "> $@"
+ native.genrule(
+ name = name,
+ srcs = [application_info_jar, application_info_name],
+ outs = [name + ".txt"],
+ cmd = cmd,
+ tools = [api_version_txt_tool],
+ **kwargs)
+
def intellij_plugin_impl(name,
deps,
plugin_xml,
diff --git a/build_defs/shared/stamp_plugin_xml.py b/build_defs/shared/stamp_plugin_xml.py
index b4fdfb6..aeaf5d2 100755
--- a/build_defs/shared/stamp_plugin_xml.py
+++ b/build_defs/shared/stamp_plugin_xml.py
@@ -3,8 +3,6 @@
import argparse
import re
from xml.dom.minidom import parse
-from xml.dom.minidom import parseString
-import zipfile
parser = argparse.ArgumentParser()
@@ -14,13 +12,8 @@
required=True,
)
parser.add_argument(
- "--application_info_jar",
- help="The jar file containing the application info xml",
- required=True,
-)
-parser.add_argument(
- "--application_info_name",
- help="A .txt file containing the application info xml name",
+ "--api_version_txt",
+ help="The file containing the api version info",
required=True,
)
parser.add_argument(
@@ -50,6 +43,14 @@
help="Changelog file to add to plugin.xml",
)
parser.add_argument(
+ "--description_file",
+ help="File with description element data to add to plugin.xml",
+)
+parser.add_argument(
+ "--vendor_file",
+ help="File with vendor element data to add to plugin.xml",
+)
+parser.add_argument(
"--include_product_code_in_stamp",
action="store_true",
help="Include the product code in the stamp",
@@ -62,60 +63,38 @@
return "\n".join("<p>" + line + "</p>" for line in f.readlines())
-def _parse_build_number(build_number):
- """Parses the build number.
+def _read_description(description_file):
+ """Reads the description and transforms it into trivial HTML."""
+ with open(description_file) as f:
+ return "\n".join("<p>" + line + "</p>" for line in f.readlines())
- Args:
- build_number: The build number as text.
- Returns:
- build_number, build_number_without_product_code.
- Raises:
- ValueError: if the build number is invalid.
- """
- match = re.match(r"^([A-Z]+-)?([0-9]+)(\.[0-9]+)?", build_number)
+
+def _read_vendor(vendor_file):
+ """Reads vendor data from an .xml file and returns the vendor element."""
+ dom = parse(vendor_file)
+ vendor_elements = dom.getElementsByTagName("vendor")
+ if len(vendor_elements) != 1:
+ raise ValueError("Ambigious or missing vendor element (%d elements)" %
+ len(vendor_elements))
+ return vendor_elements[0]
+
+
+def _strip_product_code(api_version):
+ """Strips the product code from the api version string."""
+ match = re.match(r"^([A-Z]+-)?([0-9]+)((\.[0-9]+)*)", api_version)
if match is None:
- raise ValueError("Invalid build number: " + build_number)
+ raise ValueError("Invalid build number: " + api_version)
- build_number = match.group(1) + match.group(2) + match.group(3)
- build_number_without_product_code = match.group(2) + match.group(3)
- return build_number, build_number_without_product_code
+ return match.group(2) + match.group(3)
def main():
-
args = parser.parse_args()
dom = parse(args.plugin_xml)
- with open(args.application_info_name) as f:
- application_info_name = f.read().strip()
-
- with zipfile.ZipFile(args.application_info_jar, "r") as zf:
- try:
- data = zf.read(application_info_name)
- except:
- raise ValueError("Could not read application info file: " +
- application_info_name)
- component = parseString(data)
-
- build_elements = component.getElementsByTagName("build")
- if not build_elements:
- raise ValueError("Could not find <build> element.")
- if len(build_elements) > 1:
- raise ValueError("Ambiguous <build> element.")
- build_element = build_elements[0]
-
- attrs = build_element.attributes
- if attrs.has_key("apiVersion"):
- api_version_attr = attrs.get("apiVersion")
- else:
- api_version_attr = attrs.get("number")
-
- if not api_version_attr:
- raise ValueError("Could not find api version in application info")
-
- api_version, api_version_without_product_code = _parse_build_number(
- api_version_attr.value)
+ with open(args.api_version_txt) as f:
+ api_version = f.readline().strip()
new_elements = []
@@ -145,7 +124,7 @@
idea_version_build_element = (api_version
if args.include_product_code_in_stamp else
- api_version_without_product_code)
+ _strip_product_code(api_version))
idea_version_element = dom.createElement("idea-version")
new_elements.append(idea_version_element)
@@ -182,6 +161,27 @@
name_text = dom.createTextNode(args.plugin_name)
name_element.appendChild(name_text)
+ if args.description_file:
+ if idea_plugin.getElementsByTagName("description"):
+ raise ValueError("description element already in plugin.xml")
+ description_element = dom.createElement("description")
+ description_text = _read_description(args.description_file)
+ description_cdata = dom.createCDATASection(description_text)
+ description_element.appendChild(description_cdata)
+ new_elements.append(description_element)
+
+ if args.vendor_file:
+ if idea_plugin.getElementsByTagName("vendor"):
+ raise ValueError("vendor element already in plugin.xml")
+ vendor_element = dom.createElement("vendor")
+ vendor_src_element = _read_vendor(args.vendor_file)
+ vendor_element.setAttribute("email",
+ vendor_src_element.getAttribute("email"))
+ vendor_element.setAttribute("url", vendor_src_element.getAttribute("url"))
+ vendor_text = dom.createTextNode(vendor_src_element.firstChild.data)
+ vendor_element.appendChild(vendor_text)
+ new_elements.append(vendor_element)
+
for new_element in new_elements:
idea_plugin.appendChild(new_element)
diff --git a/clwb/BUILD b/clwb/BUILD
new file mode 100644
index 0000000..792d459
--- /dev/null
+++ b/clwb/BUILD
@@ -0,0 +1,61 @@
+#
+# Description: Builds clwb
+#
+
+licenses(["notice"]) # Apache 2.0
+
+load(
+ "//build_defs:build_defs.bzl",
+ "intellij_plugin",
+ "merged_plugin_xml",
+ "stamped_plugin_xml",
+)
+
+merged_plugin_xml(
+ name = "merged_plugin_xml_common",
+ srcs = [
+ "src/META-INF/clwb.xml",
+ "//base:plugin_xml",
+ "//cpp:plugin_xml",
+ ],
+ visibility = ["//visibility:public"],
+)
+
+merged_plugin_xml(
+ name = "merged_plugin_xml",
+ srcs = [
+ "src/META-INF/clwb_bazel.xml",
+ ":merged_plugin_xml_common",
+ ],
+)
+
+stamped_plugin_xml(
+ name = "stamped_plugin_xml",
+ include_product_code_in_stamp = True,
+ plugin_id = "com.google.idea.bazel.clwb",
+ plugin_name = "CLion with Bazel",
+ plugin_xml = ":merged_plugin_xml",
+ stamp_since_build = True,
+ version_file = "//:version",
+)
+
+java_library(
+ name = "clwb_lib",
+ srcs = glob(["src/**/*.java"]),
+ visibility = ["//visibility:public"],
+ deps = [
+ "//base",
+ "//common/experiments",
+ "//cpp",
+ "//intellij_platform_sdk:plugin_api",
+ "@jsr305_annotations//jar",
+ ],
+)
+
+intellij_plugin(
+ name = "clwb_bazel",
+ plugin_xml = ":stamped_plugin_xml",
+ deps = [
+ ":clwb_lib",
+ ],
+)
diff --git a/clwb/clwb.bazelproject b/clwb/clwb.bazelproject
new file mode 100644
index 0000000..76911c2
--- /dev/null
+++ b/clwb/clwb.bazelproject
@@ -0,0 +1,19 @@
+directories:
+ .
+ -ijwb
+ -aswb
+ -plugin_dev
+ -cpp/src/com/google/idea/blaze/cpp/versioned/v145
+
+targets:
+ //clwb:clwb_bazel
+ //:clwb_tests
+
+workspace_type: intellij_plugin
+
+build_flags:
+ --define=ij_product=clion-latest
+
+test_sources:
+ */tests/unittests*
+ */tests/integrationtests*
diff --git a/clwb/src/META-INF/clwb.xml b/clwb/src/META-INF/clwb.xml
new file mode 100644
index 0000000..4cc92ef
--- /dev/null
+++ b/clwb/src/META-INF/clwb.xml
@@ -0,0 +1,73 @@
+<!--
+ ~ 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>
+ <vendor>Google</vendor>
+
+ <depends>com.intellij.modules.clion</depends>
+
+ <extensions defaultExtensionNs="com.intellij">
+ <applicationService serviceInterface="com.google.idea.blaze.base.plugin.BlazePluginId"
+ serviceImplementation="com.google.idea.blaze.plugin.ClwbPluginId"/>
+ <projectService serviceInterface="com.google.idea.blaze.base.ui.BlazeProblemsView"
+ serviceImplementation="com.google.idea.blaze.clwb.problemsview.BlazeProblemsViewConsole"/>
+ <toolWindow id="Blaze Problems View"
+ anchor="bottom"
+ secondary="true"
+ conditionClass="com.google.idea.blaze.base.settings.IsBlazeProjectCondition"
+ icon="BlazeIcons.BlazeToolWindow"
+ factoryClass="com.google.idea.blaze.clwb.problemsview.BlazeProblemsViewConsoleToolWindowFactory"/>
+ <projectService serviceInterface="com.jetbrains.cidr.lang.workspace.OCWorkspaceManager"
+ serviceImplementation="com.google.idea.blaze.clwb.cworkspace.BlazeCWorkspaceManager"
+ overrides="true"/>
+
+ <!-- run configurations -->
+ <programRunner implementation="com.google.idea.blaze.clwb.run.BlazeCppRunner"/>
+
+ <runConfigurationProducer
+ implementation="com.google.idea.blaze.clwb.run.producers.BlazeCidrTestConfigurationProducer"
+ order="first"/>
+ <!-- end run configurations -->
+ </extensions>
+
+ <extensions defaultExtensionNs="cidr.debugger">
+ <languageSupportFactory implementation="com.google.idea.blaze.clwb.run.BlazeCidrDebuggerSupportFactory"/>
+ </extensions>
+
+ <extensions defaultExtensionNs="com.google.idea.blaze">
+ <SyncPlugin implementation="com.google.idea.blaze.clwb.sync.BlazeCLionSyncPlugin"/>
+ <BlazeCommandRunConfigurationHandlerProvider implementation="com.google.idea.blaze.clwb.run.BlazeCidrRunConfigurationHandlerProvider" order="first"/>
+ </extensions>
+
+ <actions>
+ <action id="Blaze.ImportProject2" class="com.google.idea.blaze.clwb.wizard2.BlazeImportProjectAction" icon="BlazeIcons.Blaze">
+ <add-to-group group-id="WelcomeScreen.QuickStart"/>
+ <add-to-group group-id="FileOpenGroup" anchor="first"/>
+ </action>
+ </actions>
+
+ <application-components>
+ <component>
+ <implementation-class>com.google.idea.blaze.plugin.ClwbSpecificInitializer</implementation-class>
+ </component>
+ </application-components>
+
+ <project-components>
+ <component>
+ <implementation-class>com.google.idea.blaze.plugin.ClwbProjectSpecificInitializer</implementation-class>
+ </component>
+ </project-components>
+
+</idea-plugin>
diff --git a/clwb/src/META-INF/clwb_bazel.xml b/clwb/src/META-INF/clwb_bazel.xml
new file mode 100644
index 0000000..9bd8aff
--- /dev/null
+++ b/clwb/src/META-INF/clwb_bazel.xml
@@ -0,0 +1,31 @@
+<!--
+ ~ 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>
+ <description>
+ <![CDATA[
+ <a href="http://bazel.io">Bazel</a> support for CLion.
+
+ Features:
+ <ul>
+ <li>Import BUILD files into the IDE.</li>
+ <li>BUILD file custom language support.</li>
+ <li>Support for Bazel run configurations for certain rule classes.</li>
+ </ul>
+
+ Usage instructions at <a href="http://ij.bazel.io">ij.bazel.io</a>
+ ]]>
+ </description>
+</idea-plugin>
\ No newline at end of file
diff --git a/clwb/src/com/google/idea/blaze/clwb/cworkspace/BlazeCWorkspaceManager.java b/clwb/src/com/google/idea/blaze/clwb/cworkspace/BlazeCWorkspaceManager.java
new file mode 100644
index 0000000..fe6c961
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/cworkspace/BlazeCWorkspaceManager.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.cworkspace;
+
+import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.cpp.BlazeCWorkspace;
+import com.intellij.openapi.project.Project;
+import com.jetbrains.cidr.lang.CPPWorkspaceManager;
+import com.jetbrains.cidr.lang.workspace.OCWorkspace;
+import com.jetbrains.cidr.lang.workspace.OCWorkspaceManager;
+
+class BlazeCWorkspaceManager extends OCWorkspaceManager {
+ private final Project project;
+ private final OCWorkspaceManager delegate;
+
+ public BlazeCWorkspaceManager(Project project) {
+ this.project = project;
+ this.delegate = new CPPWorkspaceManager(project);
+ }
+
+ @Override
+ public OCWorkspace getWorkspace() {
+ if (Blaze.isBlazeProject(project)) {
+ return BlazeCWorkspace.getInstance(project);
+ }
+ // this is a gross hack, necessitated by OCWorkspaceManager being a service, rather than
+ // using extension points. We don't actually know which OCWorkspaceManager would be used
+ // if this one wasn't overriding -- but we'll guess that it was CPPWorkspaceManager...
+ return delegate.getWorkspace();
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsole.java b/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsole.java
new file mode 100644
index 0000000..07703e3
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsole.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.problemsview;
+
+import com.google.idea.blaze.base.scope.output.IssueOutput;
+import com.google.idea.blaze.base.ui.BlazeProblemsView;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.errorTreeView.ErrorTreeElement;
+import com.intellij.ide.errorTreeView.ErrorTreeElementKind;
+import com.intellij.ide.errorTreeView.ErrorViewStructure;
+import com.intellij.ide.errorTreeView.GroupingElement;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.IconLoader;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.pom.Navigatable;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentFactory;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.concurrency.SequentialTaskExecutor;
+import com.intellij.util.ui.MessageCategory;
+import com.intellij.util.ui.UIUtil;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.UUID;
+import javax.swing.Icon;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.ide.PooledThreadExecutor;
+
+/** @author Eugene Zhuravlev Date: 9/18/12 */
+public class BlazeProblemsViewConsole implements BlazeProblemsView {
+ private static final Logger LOG = Logger.getInstance(BlazeProblemsViewConsole.class);
+
+ private static final String BLAZE_PROBLEMS_TOOLWINDOW_ID = "Blaze Problems";
+ private static final EnumSet<ErrorTreeElementKind> ALL_MESSAGE_KINDS =
+ EnumSet.allOf(ErrorTreeElementKind.class);
+
+ private final ProblemsViewPanel myPanel;
+ private final SequentialTaskExecutor myViewUpdater =
+ new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE);
+ private final Icon myActiveIcon = AllIcons.Toolwindows.Problems;
+ private final Icon myPassiveIcon = IconLoader.getDisabledIcon(myActiveIcon);
+
+ private final Project myProject;
+
+ public static BlazeProblemsViewConsole getImpl(Project project) {
+ BlazeProblemsViewConsole blazeProblemsViewConsole =
+ (BlazeProblemsViewConsole) ServiceManager.getService(project, BlazeProblemsView.class);
+ LOG.assertTrue(blazeProblemsViewConsole != null);
+ return blazeProblemsViewConsole;
+ }
+
+ public BlazeProblemsViewConsole(final Project project) {
+ myProject = project;
+ myPanel = new ProblemsViewPanel(project);
+ Disposer.register(project, () -> Disposer.dispose(myPanel));
+ }
+
+ public void createToolWindowContent(ToolWindow toolWindow) {
+ final Content content = ContentFactory.SERVICE.getInstance().createContent(myPanel, "", false);
+ toolWindow.getContentManager().addContent(content);
+ Disposer.register(myProject, () -> toolWindow.getContentManager().removeAllContents(true));
+ updateIcon();
+ }
+
+ @Override
+ public final void addMessage(IssueOutput issue, @NotNull UUID sessionId) {
+ final VirtualFile file =
+ issue.getFile() != null
+ ? VfsUtil.findFileByIoFile(issue.getFile(), true /* refresh */)
+ : null;
+ Navigatable navigatable = issue.getNavigatable();
+ if (navigatable == null && file != null) {
+ navigatable = new OpenFileDescriptor(myProject, file, -1, -1);
+ }
+ final IssueOutput.Category category = issue.getCategory();
+ final int type = translateCategory(category);
+ final String[] text = convertMessage(issue);
+ final String groupName = file != null ? file.getPresentableUrl() : category.name();
+ addMessage(
+ type,
+ text,
+ groupName,
+ navigatable,
+ getExportTextPrefix(issue),
+ getRenderTextPrefix(issue),
+ sessionId);
+ }
+
+ private static int translateCategory(IssueOutput.Category category) {
+ switch (category) {
+ case ERROR:
+ return MessageCategory.ERROR;
+ case WARNING:
+ return MessageCategory.WARNING;
+ case STATISTICS:
+ return MessageCategory.STATISTICS;
+ case INFORMATION:
+ return MessageCategory.INFORMATION;
+ default:
+ LOG.error("Unknown message category: " + category);
+ return 0;
+ }
+ }
+
+ private static String[] convertMessage(final IssueOutput issue) {
+ String text = issue.getMessage();
+ if (!text.contains("\n")) {
+ return new String[] {text};
+ }
+ final List<String> lines = new ArrayList<String>();
+ StringTokenizer tokenizer = new StringTokenizer(text, "\n", false);
+ while (tokenizer.hasMoreTokens()) {
+ lines.add(tokenizer.nextToken());
+ }
+ return ArrayUtil.toStringArray(lines);
+ }
+
+ private static String getExportTextPrefix(IssueOutput issue) {
+ int line = issue.getLine();
+ if (line >= 0) {
+ return String.format("line: %d", line);
+ }
+ return "";
+ }
+
+ private static String getRenderTextPrefix(IssueOutput issue) {
+ int line = issue.getLine();
+ if (line >= 0) {
+ return String.format("(%d, %d)", line, issue.getColumn());
+ }
+ return "";
+ }
+
+ @Override
+ public void clearOldMessages(@NotNull final UUID currentSessionId) {
+ myViewUpdater.execute(
+ new Runnable() {
+ @Override
+ public void run() {
+ cleanupChildrenRecursively(
+ myPanel.getErrorViewStructure().getRootElement(), currentSessionId);
+ updateIcon();
+ myPanel.reload();
+ }
+ });
+ }
+
+ private void cleanupChildrenRecursively(
+ @NotNull final Object fromElement, @NotNull UUID currentSessionId) {
+ final ErrorViewStructure structure = myPanel.getErrorViewStructure();
+ for (ErrorTreeElement element : structure.getChildElements(fromElement)) {
+ if (element instanceof GroupingElement) {
+ if (!currentSessionId.equals(element.getData())) {
+ structure.removeElement(element);
+ } else {
+ cleanupChildrenRecursively(element, currentSessionId);
+ }
+ } else {
+ if (!currentSessionId.equals(element.getData())) {
+ structure.removeElement(element);
+ }
+ }
+ }
+ }
+
+ public void addMessage(
+ final int type,
+ @NotNull final String[] text,
+ @Nullable final String groupName,
+ @Nullable final Navigatable navigatable,
+ @Nullable final String exportTextPrefix,
+ @Nullable final String rendererTextPrefix,
+ @Nullable final UUID sessionId) {
+
+ myViewUpdater.execute(
+ new Runnable() {
+ @Override
+ public void run() {
+ final ErrorViewStructure structure = myPanel.getErrorViewStructure();
+ final GroupingElement group = structure.lookupGroupingElement(groupName);
+ if (group != null && sessionId != null && !sessionId.equals(group.getData())) {
+ structure.removeElement(group);
+ }
+ if (navigatable != null) {
+ myPanel.addMessage(
+ type,
+ text,
+ groupName,
+ navigatable,
+ exportTextPrefix,
+ rendererTextPrefix,
+ sessionId);
+ } else {
+ myPanel.addMessage(type, text, null, -1, -1, sessionId);
+ }
+ updateIcon();
+ }
+ });
+ }
+
+ private void updateIcon() {
+ UIUtil.invokeLaterIfNeeded(
+ new Runnable() {
+ @Override
+ public void run() {
+ if (!myProject.isDisposed()) {
+ final ToolWindow tw =
+ ToolWindowManager.getInstance(myProject)
+ .getToolWindow(BLAZE_PROBLEMS_TOOLWINDOW_ID);
+ if (tw != null) {
+ final boolean active =
+ myPanel.getErrorViewStructure().hasMessages(ALL_MESSAGE_KINDS);
+ tw.setIcon(active ? myActiveIcon : myPassiveIcon);
+ }
+ }
+ }
+ });
+ }
+
+ public void setProgress(String text, float fraction) {
+ myPanel.setProgress(text, fraction);
+ }
+
+ public void setProgress(String text) {
+ myPanel.setProgressText(text);
+ }
+
+ public void clearProgress() {
+ myPanel.clearProgressData();
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsoleToolWindowFactory.java b/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsoleToolWindowFactory.java
new file mode 100644
index 0000000..20ba562
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/problemsview/BlazeProblemsViewConsoleToolWindowFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.problemsview;
+
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowFactory;
+
+/** Factory for console window. */
+public class BlazeProblemsViewConsoleToolWindowFactory implements DumbAware, ToolWindowFactory {
+ @Override
+ public void createToolWindowContent(Project project, ToolWindow toolWindow) {
+ BlazeProblemsViewConsole blazeProblemsViewConsole = BlazeProblemsViewConsole.getImpl(project);
+ blazeProblemsViewConsole.createToolWindowContent(toolWindow);
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/problemsview/ProblemsViewPanel.java b/clwb/src/com/google/idea/blaze/clwb/problemsview/ProblemsViewPanel.java
new file mode 100644
index 0000000..a16636b
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/problemsview/ProblemsViewPanel.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.problemsview;
+
+import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.project.Project;
+
+class ProblemsViewPanel extends NewErrorTreeViewPanel {
+ ProblemsViewPanel(Project project) {
+ super(project, "blaze.problems.tool.window", false, true, null);
+ myTree.getEmptyText().setText("No problems found");
+ }
+
+ @Override
+ protected void fillRightToolbarGroup(DefaultActionGroup group) {
+ super.fillRightToolbarGroup(group);
+ }
+
+ @Override
+ protected void addExtraPopupMenuActions(DefaultActionGroup group) {}
+
+ @Override
+ protected boolean shouldShowFirstErrorInEditor() {
+ return false;
+ }
+
+ @Override
+ protected boolean canHideWarnings() {
+ return false;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrDebuggerSupportFactory.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrDebuggerSupportFactory.java
new file mode 100644
index 0000000..2e7a019
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrDebuggerSupportFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.intellij.execution.configurations.RunProfile;
+import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.jetbrains.cidr.execution.debugger.OCDebuggerLanguageSupportFactory;
+import javax.annotation.Nullable;
+
+/**
+ * A version of {@link OCDebuggerLanguageSupportFactory} which can accept {@link
+ * BlazeCommandRunConfiguration} when appropriate.
+ */
+public class BlazeCidrDebuggerSupportFactory extends OCDebuggerLanguageSupportFactory {
+ @Nullable
+ @Override
+ public XDebuggerEditorsProvider createEditor(RunProfile profile) {
+ if (profile instanceof BlazeCommandRunConfiguration
+ && RunConfigurationUtils.canUseClionRunner((BlazeCommandRunConfiguration) profile)) {
+ return createEditorProvider();
+ }
+ return null;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrLauncher.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrLauncher.java
new file mode 100644
index 0000000..70f249e
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrLauncher.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.common.collect.ImmutableList;
+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.issueparser.IssueOutputLineProcessor;
+import com.google.idea.blaze.base.metrics.Action;
+import com.google.idea.blaze.base.metrics.LoggingService;
+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.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.processhandler.LineProcessingProcessAdapter;
+import com.google.idea.blaze.base.run.processhandler.ScopedBlazeProcessHandler;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.scope.scopes.IssuesScope;
+import com.google.idea.blaze.base.scope.scopes.LoggedTimingScope;
+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.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.CommandLineState;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.process.ProcessListener;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.execution.ui.ConsoleView;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.xdebugger.XDebugSession;
+import com.jetbrains.cidr.cpp.execution.CLionRunParameters;
+import com.jetbrains.cidr.execution.CidrConsoleBuilder;
+import com.jetbrains.cidr.execution.TrivialInstaller;
+import com.jetbrains.cidr.execution.debugger.CidrDebugProcess;
+import com.jetbrains.cidr.execution.debugger.CidrLocalDebugProcess;
+import com.jetbrains.cidr.execution.testing.CidrLauncher;
+import com.jetbrains.cidr.execution.testing.OCGoogleTestConsoleProperties;
+import java.io.File;
+import java.util.Objects;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Handles running/debugging cc_test and cc_binary targets in CLion. Sets up gdb when debugging, and
+ * uses the Google Test infrastructure for presenting test results.
+ */
+public final class BlazeCidrLauncher extends CidrLauncher {
+ private static final Logger LOG = Logger.getInstance(BlazeCidrLauncher.class);
+
+ private final Project project;
+ private final BlazeCommandRunConfiguration configuration;
+ private final BlazeCommandRunConfigurationCommonState handlerState;
+ private final BlazeCidrRunConfigurationRunner runner;
+ private final ExecutionEnvironment executionEnvironment;
+
+ public BlazeCidrLauncher(
+ BlazeCommandRunConfiguration configuration,
+ BlazeCidrRunConfigurationRunner runner,
+ ExecutionEnvironment environment) {
+ this.configuration = configuration;
+ this.handlerState =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
+ this.runner = runner;
+ this.executionEnvironment = environment;
+ this.project = configuration.getProject();
+ }
+
+ @Override
+ public ProcessHandler createProcess(CommandLineState state) throws ExecutionException {
+ BlazeImportSettings importSettings =
+ BlazeImportSettingsManager.getInstance(project).getImportSettings();
+ LOG.assertTrue(importSettings != null);
+
+ ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
+ LOG.assertTrue(projectViewSet != null);
+
+ state.setConsoleBuilder(createConsoleBuilder());
+
+ BlazeCommand blazeCommand =
+ BlazeCommand.builder(Blaze.getBuildSystem(project), handlerState.getCommand())
+ .addTargets(configuration.getTarget())
+ .addBlazeFlags(BlazeFlags.buildFlags(project, ProjectViewSet.builder().build()))
+ .addBlazeFlags(handlerState.getBlazeFlags())
+ .addExeFlags(handlerState.getExeFlags())
+ .build();
+
+ WorkspaceRoot workspaceRoot = WorkspaceRoot.fromImportSettings(importSettings);
+ return new ScopedBlazeProcessHandler(
+ project,
+ blazeCommand,
+ workspaceRoot,
+ new ScopedBlazeProcessHandler.ScopedProcessHandlerDelegate() {
+ @Override
+ public void onBlazeContextStart(BlazeContext context) {
+ context
+ .push(new LoggedTimingScope(project, Action.BLAZE_COMMAND_USAGE))
+ .push(new LoggedTimingScope(project, Action.BLAZE_CLION_TEST_RUN))
+ .push(new IssuesScope(project));
+ }
+
+ @Override
+ public ImmutableList<ProcessListener> createProcessListeners(BlazeContext context) {
+ LineProcessingOutputStream outputStream =
+ LineProcessingOutputStream.of(
+ new IssueOutputLineProcessor(project, context, workspaceRoot));
+ return ImmutableList.of(new LineProcessingProcessAdapter(outputStream));
+ }
+ });
+ }
+
+ @Override
+ public CidrDebugProcess createDebugProcess(CommandLineState state, XDebugSession session)
+ throws ExecutionException {
+ TargetExpression target = configuration.getTarget();
+ if (target == null) {
+ return null;
+ }
+ if (runner.executableToDebug == null) {
+ return null;
+ }
+ ProjectViewSet projectViewSet = ProjectViewManager.getInstance(project).getProjectViewSet();
+ LOG.assertTrue(projectViewSet != null);
+ WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
+
+ GeneralCommandLine commandLine = new GeneralCommandLine(runner.executableToDebug.getPath());
+ File workingDir = workspaceRoot.directory();
+ commandLine.setWorkDirectory(workingDir);
+
+ TrivialInstaller installer = new TrivialInstaller(commandLine);
+ ImmutableList<String> startupCommands = getGdbStartupCommands(workingDir);
+ CLionRunParameters parameters =
+ new CLionRunParameters(
+ new BlazeGDBDriverConfiguration(project, startupCommands, workspaceRoot), installer);
+ CidrDebugProcess result =
+ new CidrLocalDebugProcess(parameters, session, state.getConsoleBuilder());
+
+ LoggingService.reportEvent(project, Action.BLAZE_CLION_TEST_DEBUG);
+ return result;
+ }
+
+ @NotNull
+ @Override
+ protected Project getProject() {
+ return project;
+ }
+
+ private CidrConsoleBuilder createConsoleBuilder() {
+ if (Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)) {
+ // Use the Google Test failure/success console instead of a standard console.
+ return new GoogleTestConsoleBuilder(configuration.getProject());
+ }
+ return new CidrConsoleBuilder(configuration.getProject());
+ }
+
+ private ImmutableList<String> getGdbStartupCommands(File workingDir) {
+ // Forge creates debug symbol paths rooted at /proc/self/cwd .
+ // We need to tell gdb to translate this path prefix to the user's workspace
+ // root so the IDE can find the files.
+ String from = "/proc/self/cwd";
+ String to = workingDir.getPath();
+ String subPathCommand = String.format("set substitute-path %s %s", from, to);
+
+ return ImmutableList.of(subPathCommand);
+ }
+
+ private final class GoogleTestConsoleBuilder extends CidrConsoleBuilder {
+ private GoogleTestConsoleBuilder(Project project) {
+ super(project);
+ }
+
+ @Override
+ protected ConsoleView createConsole() {
+ OCGoogleTestConsoleProperties consoleProperties =
+ new OCGoogleTestConsoleProperties(
+ configuration,
+ executionEnvironment.getExecutor(),
+ executionEnvironment.getExecutionTarget());
+ return createConsole(configuration.getType(), consoleProperties);
+ }
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationHandler.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationHandler.java
new file mode 100644
index 0000000..29aea18
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationHandler.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationRunner;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.intellij.execution.Executor;
+import com.intellij.execution.RunnerAndConfigurationSettings;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.execution.configurations.RuntimeConfigurationException;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import javax.annotation.Nullable;
+import javax.swing.Icon;
+
+/** CLion-specific handler for {@link BlazeCommandRunConfiguration}s. */
+public final class BlazeCidrRunConfigurationHandler implements BlazeCommandRunConfigurationHandler {
+
+ private final String buildSystemName;
+ private final BlazeCommandRunConfigurationCommonState state;
+
+ public BlazeCidrRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
+ this.buildSystemName = Blaze.buildSystemName(configuration.getProject());
+ this.state = new BlazeCommandRunConfigurationCommonState(buildSystemName);
+ }
+
+ @Override
+ public BlazeCommandRunConfigurationCommonState getState() {
+ return state;
+ }
+
+ @Override
+ public BlazeCommandRunConfigurationRunner createRunner(
+ Executor executor, ExecutionEnvironment environment) {
+ RunnerAndConfigurationSettings settings = environment.getRunnerAndConfigurationSettings();
+ RunConfiguration config = settings != null ? settings.getConfiguration() : null;
+ if (config instanceof BlazeCommandRunConfiguration
+ && RunConfigurationUtils.canUseClionRunner((BlazeCommandRunConfiguration) config)) {
+ return new BlazeCidrRunConfigurationRunner((BlazeCommandRunConfiguration) config);
+ }
+ return new BlazeCommandGenericRunConfigurationRunner();
+ }
+
+ @Override
+ public void checkConfiguration() throws RuntimeConfigurationException {
+ state.validate(buildSystemName);
+ }
+
+ @Override
+ @Nullable
+ public String suggestedName(BlazeCommandRunConfiguration configuration) {
+ if (configuration.getTarget() == null) {
+ return null;
+ }
+ return new BlazeConfigurationNameBuilder(configuration).build();
+ }
+
+ @Override
+ @Nullable
+ public String getCommandName() {
+ BlazeCommandName command = state.getCommand();
+ return command != null ? command.toString() : null;
+ }
+
+ @Override
+ public String getHandlerName() {
+ return "CLion Handler";
+ }
+
+ @Override
+ @Nullable
+ public Icon getExecutorIcon(RunConfiguration configuration, Executor executor) {
+ return null;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationHandlerProvider.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationHandlerProvider.java
new file mode 100644
index 0000000..6d78d29
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationHandlerProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.idea.blaze.base.model.primitives.Kind;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerProvider;
+
+/** CLion-specific handler for {@link BlazeCommandRunConfiguration}s. */
+public class BlazeCidrRunConfigurationHandlerProvider
+ implements BlazeCommandRunConfigurationHandlerProvider {
+
+ @Override
+ public boolean canHandleKind(Kind kind) {
+ return RunConfigurationUtils.canUseClionHandler(kind);
+ }
+
+ @Override
+ public BlazeCommandRunConfigurationHandler createHandler(BlazeCommandRunConfiguration config) {
+ return new BlazeCidrRunConfigurationHandler(config);
+ }
+
+ @Override
+ public String getId() {
+ return "BlazeCLionRunConfigurationHandlerProvider";
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java
new file mode 100644
index 0000000..515e4bb
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+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.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.ExperimentalShowArtifactsLineProcessor;
+import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
+import com.google.idea.blaze.base.metrics.Action;
+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.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.scope.ScopedTask;
+import com.google.idea.blaze.base.scope.output.StatusOutput;
+import com.google.idea.blaze.base.scope.scopes.BlazeConsoleScope;
+import com.google.idea.blaze.base.scope.scopes.IssuesScope;
+import com.google.idea.blaze.base.scope.scopes.LoggedTimingScope;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.util.SaveUtil;
+import com.google.idea.common.experiments.BoolExperiment;
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.Executor;
+import com.intellij.execution.configurations.RunProfileState;
+import com.intellij.execution.executors.DefaultDebugExecutor;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.jetbrains.cidr.execution.CidrCommandLineState;
+import java.io.File;
+import java.util.List;
+
+/** CLion-specific handler for {@link BlazeCommandRunConfiguration}s. */
+public class BlazeCidrRunConfigurationRunner implements BlazeCommandRunConfigurationRunner {
+
+ private static final Logger LOG = Logger.getInstance(ExternalTask.class);
+
+ private static final BoolExperiment FORCE_DEBUG_BUILD_FOR_DEBUGGING_TEST =
+ new BoolExperiment("clwb.force.debug.build.for.debugging.test", true);
+
+ private final BlazeCommandRunConfiguration configuration;
+
+ /** Calculated during the before-run task, and made available to the debugger. */
+ File executableToDebug = null;
+
+ BlazeCidrRunConfigurationRunner(BlazeCommandRunConfiguration configuration) {
+ this.configuration = configuration;
+ }
+
+ @Override
+ public RunProfileState getRunProfileState(Executor executor, ExecutionEnvironment env) {
+ return new CidrCommandLineState(env, new BlazeCidrLauncher(configuration, this, env));
+ }
+
+ @Override
+ public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
+ if (!isDebugging(environment)) {
+ return true;
+ }
+ try {
+ File executable = getExecutableToDebug();
+ if (executable != null) {
+ executableToDebug = executable;
+ return true;
+ }
+ } catch (ExecutionException e) {
+ LOG.error(e.getMessage());
+ }
+ return false;
+ }
+
+ private static boolean isDebugging(ExecutionEnvironment environment) {
+ Executor executor = environment.getExecutor();
+ return executor instanceof DefaultDebugExecutor;
+ }
+
+ /**
+ * Builds blaze C/C++ target in debug mode, and returns the output build artifact.
+ *
+ * @throws ExecutionException if no unique output artifact was found.
+ */
+ private File getExecutableToDebug() throws ExecutionException {
+ final Project project = configuration.getProject();
+ final BlazeCommandRunConfigurationCommonState handlerState =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
+ final WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
+ final ProjectViewSet projectViewSet =
+ ProjectViewManager.getInstance(project).getProjectViewSet();
+
+ final List<File> outputArtifacts = Lists.newArrayList();
+ final ListenableFuture<Void> buildOperation =
+ BlazeExecutor.submitTask(
+ project,
+ new ScopedTask() {
+ @Override
+ protected void execute(BlazeContext context) {
+ context
+ .push(new LoggedTimingScope(project, Action.BLAZE_COMMAND_USAGE))
+ .push(new IssuesScope(project))
+ .push(new BlazeConsoleScope.Builder(project).build());
+ ;
+
+ context.output(new StatusOutput("Building debug binary"));
+
+ BlazeCommand.Builder command =
+ BlazeCommand.builder(Blaze.getBuildSystem(project), BlazeCommandName.BUILD)
+ .addTargets(configuration.getTarget())
+ .addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
+ .addBlazeFlags(handlerState.getBlazeFlags())
+ .addExeFlags(handlerState.getExeFlags());
+
+ command.addBlazeFlags("--experimental_show_artifacts");
+
+ // If we are trying to debug, make sure we are building in debug mode.
+ // This can cause a rebuild, so it is a heavyweight setting.
+ if (FORCE_DEBUG_BUILD_FOR_DEBUGGING_TEST.getValue()) {
+ command.addBlazeFlags("-c", "dbg");
+ }
+
+ ExternalTask.builder(workspaceRoot)
+ .addBlazeCommand(command.build())
+ .context(context)
+ .stderr(
+ LineProcessingOutputStream.of(
+ new ExperimentalShowArtifactsLineProcessor(outputArtifacts, ""),
+ new IssueOutputLineProcessor(project, context, workspaceRoot)))
+ .build()
+ .run();
+ }
+ });
+
+ try {
+ SaveUtil.saveAllFiles();
+ buildOperation.get();
+ } catch (InterruptedException | java.util.concurrent.ExecutionException e) {
+ throw new ExecutionException(e);
+ }
+ if (outputArtifacts.isEmpty()) {
+ throw new ExecutionException(
+ String.format("No output artifacts found when building %s", configuration.getTarget()));
+ }
+ if (outputArtifacts.size() > 1) {
+ throw new ExecutionException(
+ String.format(
+ "More than 1 executable was produced when building %s; don't know which one to debug",
+ configuration.getTarget()));
+ }
+ LocalFileSystem.getInstance().refreshIoFiles(outputArtifacts);
+ return Iterables.getOnlyElement(outputArtifacts);
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCommandFlags.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCommandFlags.java
new file mode 100644
index 0000000..12020f2
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCommandFlags.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.ui.UiUtil;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.util.execution.ParametersListUtil;
+import java.util.List;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JTextArea;
+import org.jdom.Element;
+
+final class BlazeCommandFlags implements JDOMExternalizable {
+ public static final class Editor {
+ private final JTextArea blazeFlagsField = new JTextArea(5, 0);
+ private final JTextArea exeFlagsField = new JTextArea(5, 0);
+
+ public JComponent getEditorComponent() {
+ return UiUtil.createBox(
+ new JLabel("Blaze flags:"),
+ blazeFlagsField,
+ new JLabel("Executable flags:"),
+ exeFlagsField);
+ }
+
+ public void setText(BlazeCommandFlags blazeCommandFlags) {
+ blazeFlagsField.setText(ParametersListUtil.join(blazeCommandFlags.getBlazeFlags()));
+ exeFlagsField.setText(ParametersListUtil.join(blazeCommandFlags.getExeFlags()));
+ }
+
+ public BlazeCommandFlags getBlazeCommandFlags() {
+ ImmutableList<String> blazeFlags =
+ ImmutableList.copyOf(
+ ParametersListUtil.parse(Strings.nullToEmpty(blazeFlagsField.getText())));
+ ImmutableList<String> exeFlags =
+ ImmutableList.copyOf(
+ ParametersListUtil.parse(Strings.nullToEmpty(exeFlagsField.getText())));
+ return new BlazeCommandFlags(blazeFlags, exeFlags);
+ }
+ }
+
+ private static final String USER_BLAZE_FLAG_TAG = "blaze-user-flag";
+ private static final String USER_EXE_FLAG_TAG = "blaze-user-exe-flag";
+
+ private ImmutableList<String> blazeFlags = ImmutableList.of();
+ private ImmutableList<String> exeFlags = ImmutableList.of();
+
+ public BlazeCommandFlags() {
+ this.blazeFlags = ImmutableList.of();
+ this.exeFlags = ImmutableList.of();
+ }
+
+ public BlazeCommandFlags(ImmutableList<String> blazeFlags, ImmutableList<String> exeFlags) {
+ this.blazeFlags = blazeFlags;
+ this.exeFlags = exeFlags;
+ }
+
+ public ImmutableList<String> getBlazeFlags() {
+ return blazeFlags;
+ }
+
+ public ImmutableList<String> getExeFlags() {
+ return exeFlags;
+ }
+
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ blazeFlags = loadUserFlags(element, USER_BLAZE_FLAG_TAG);
+ exeFlags = loadUserFlags(element, USER_EXE_FLAG_TAG);
+ }
+
+ private static ImmutableList<String> loadUserFlags(Element root, String tag) {
+ ImmutableList.Builder<String> flagsBuilder = ImmutableList.builder();
+ for (Element e : root.getChildren(tag)) {
+ String flag = e.getTextTrim();
+ if (flag != null && !flag.isEmpty()) {
+ flagsBuilder.add(flag);
+ }
+ }
+ return flagsBuilder.build();
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ saveUserFlags(element, blazeFlags, USER_BLAZE_FLAG_TAG);
+ saveUserFlags(element, exeFlags, USER_EXE_FLAG_TAG);
+ }
+
+ private static void saveUserFlags(Element root, List<String> flags, String tag) {
+ for (String flag : flags) {
+ Element child = new Element(tag);
+ child.setText(flag);
+ root.addContent(child);
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ BlazeCommandFlags that = (BlazeCommandFlags) o;
+ return Objects.equal(blazeFlags, that.blazeFlags) && Objects.equal(exeFlags, that.exeFlags);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(blazeFlags, exeFlags);
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCppRunner.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCppRunner.java
new file mode 100644
index 0000000..506cbd5
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCppRunner.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.intellij.execution.configurations.RunProfile;
+import com.jetbrains.cidr.cpp.execution.CLionRunner;
+
+/**
+ * A version of CPPRunner which can accept {@link BlazeCommandRunConfiguration} when appropriate.
+ */
+public class BlazeCppRunner extends CLionRunner {
+
+ @Override
+ public String getRunnerId() {
+ return "BlazeCppAppRunner";
+ }
+
+ @Override
+ public boolean canRun(String executorId, RunProfile profile) {
+ return profile instanceof BlazeCommandRunConfiguration
+ && RunConfigurationUtils.canUseClionRunner((BlazeCommandRunConfiguration) profile);
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeGDBDriverConfiguration.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeGDBDriverConfiguration.java
new file mode 100644
index 0000000..82c6a5f
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeGDBDriverConfiguration.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.jetbrains.cidr.cpp.execution.debugger.backend.GDBDriverConfiguration;
+import com.jetbrains.cidr.execution.Installer;
+import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriver;
+import java.io.File;
+import java.io.IOException;
+import javax.annotation.Nullable;
+
+final class BlazeGDBDriverConfiguration extends GDBDriverConfiguration {
+ private static final Logger LOG = Logger.getInstance(BlazeGDBDriverConfiguration.class);
+
+ private final ImmutableList<String> startupCommands;
+ private final WorkspaceRoot workspaceRoot;
+ private final Project project;
+
+ BlazeGDBDriverConfiguration(
+ Project project, ImmutableList<String> startupCommands, WorkspaceRoot workspaceRoot) {
+ this.project = project;
+ this.startupCommands = startupCommands;
+ this.workspaceRoot = workspaceRoot;
+ }
+
+ @Override
+ public GeneralCommandLine createDriverCommandLine(DebuggerDriver driver, Installer installer)
+ throws ExecutionException {
+ GeneralCommandLine driverCommandLine = super.createDriverCommandLine(driver, installer);
+
+ // Add our GDB commands to run after startup
+ for (String command : startupCommands) {
+ driverCommandLine.addParameter("-ex");
+ driverCommandLine.addParameter(command);
+ }
+ return driverCommandLine;
+ }
+
+ @Override
+ public String convertToLocalPath(@Nullable String absolutePath) {
+ if (absolutePath != null) {
+ final File file = new File(absolutePath);
+ final File workspaceDirectory = workspaceRoot.directory();
+ final String relativePath = gdbPathToWorkspaceRelativePath(workspaceDirectory, file);
+ File git5SafeFile = null;
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
+ if (blazeProjectData != null) {
+ git5SafeFile = blazeProjectData.workspacePathResolver.resolveToFile(relativePath);
+ }
+ absolutePath = git5SafeFile == null ? null : git5SafeFile.getPath();
+ }
+ return super.convertToLocalPath(absolutePath);
+ }
+
+ /**
+ * Heuristic to try to handle the case where the file returned by gdb uses the canonical path but
+ * the user imported their project using a non-canonical path. For example, this handles the case
+ * where the user keeps their git5 repos on a different mount and accesses them via a symlink from
+ * their home directory.
+ *
+ * @param workspaceDirectory workspace root, as it was imported into CLion
+ * @param file file returned by GDB
+ * @return The relative path for {@param file} as it was imported into CLion
+ */
+ private String gdbPathToWorkspaceRelativePath(File workspaceDirectory, File file) {
+ try {
+ File canonicalWorkspaceDirectory = workspaceDirectory.getCanonicalFile();
+ File canonicalFile = file.getCanonicalFile();
+ String relativeCanonicalPath =
+ FileUtil.getRelativePath(canonicalWorkspaceDirectory, canonicalFile);
+ if (relativeCanonicalPath != null) {
+ return relativeCanonicalPath;
+ }
+ } catch (IOException e) {
+ LOG.info(e);
+ }
+ return file.getPath();
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/RunConfigurationUtils.java b/clwb/src/com/google/idea/blaze/clwb/run/RunConfigurationUtils.java
new file mode 100644
index 0000000..a6c96ad
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/RunConfigurationUtils.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.model.primitives.Kind;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+
+/** Utility methods for CLion run configurations */
+public class RunConfigurationUtils {
+
+ static boolean canUseClionHandler(Kind kind) {
+ return kind == Kind.CC_TEST || kind == Kind.CC_BINARY;
+ }
+
+ static boolean canUseClionRunner(BlazeCommandRunConfiguration config) {
+ Kind kind = config.getKindForTarget();
+ BlazeCommandRunConfigurationCommonState handlerState =
+ config.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
+ return false;
+ }
+ BlazeCommandName command = handlerState.getCommand();
+ return kind != null
+ && command != null
+ && ((kind == Kind.CC_TEST && command.equals(BlazeCommandName.TEST))
+ || (kind == Kind.CC_BINARY && command.equals(BlazeCommandName.BUILD)));
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java b/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java
new file mode 100644
index 0000000..3132f87
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run.producers;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
+import com.google.idea.blaze.base.run.TestRuleFinder;
+import com.google.idea.blaze.base.run.TestRuleHeuristic;
+import com.google.idea.blaze.base.run.producers.BlazeRunConfigurationProducer;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.intellij.execution.Location;
+import com.intellij.execution.actions.ConfigurationContext;
+import com.intellij.openapi.util.Couple;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.jetbrains.cidr.execution.testing.CidrTestUtil;
+import com.jetbrains.cidr.lang.psi.OCFile;
+import com.jetbrains.cidr.lang.psi.OCFunctionDefinition;
+import com.jetbrains.cidr.lang.psi.OCMacroCall;
+import com.jetbrains.cidr.lang.psi.OCMacroCallArgument;
+import com.jetbrains.cidr.lang.psi.OCStruct;
+import com.jetbrains.cidr.lang.symbols.OCSymbol;
+import com.jetbrains.cidr.lang.symbols.cpp.OCFunctionSymbol;
+import com.jetbrains.cidr.lang.symbols.cpp.OCStructSymbol;
+import com.jetbrains.cidr.lang.symbols.cpp.OCSymbolWithQualifiedName;
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import javax.annotation.Nullable;
+
+/** Producer for run configurations related to C/C++ test classes in Blaze. */
+public class BlazeCidrTestConfigurationProducer
+ extends BlazeRunConfigurationProducer<BlazeCommandRunConfiguration> {
+
+ private static class TestTarget {
+ @Nullable
+ private static TestTarget createFromFile(@Nullable PsiElement element) {
+ return createFromClassAndMethod(element, null, null);
+ }
+
+ @Nullable
+ private static TestTarget createFromClass(@Nullable PsiElement element, String className) {
+ return createFromClassAndMethod(element, className, null);
+ }
+
+ @Nullable
+ private static TestTarget createFromClassAndMethod(
+ @Nullable PsiElement element, String classOrSuiteName, @Nullable String testName) {
+ Label label = getCcTestTarget(element);
+ if (label == null) {
+ return null;
+ }
+ String filter = null;
+ if (classOrSuiteName != null) {
+ filter = classOrSuiteName;
+ if (testName != null) {
+ filter += "." + testName;
+ }
+ }
+ return new TestTarget(element, label, filter);
+ }
+
+ private final PsiElement element;
+ private final Label label;
+ @Nullable private final String testFilterArg;
+ private final String name;
+
+ private TestTarget(PsiElement element, Label label, @Nullable String testFilter) {
+ this.element = element;
+ this.label = label;
+ if (testFilter != null) {
+ testFilterArg = BlazeFlags.TEST_FILTER + "=" + testFilter;
+ name = String.format("%s (%s)", testFilter, label.toString());
+ } else {
+ testFilterArg = null;
+ name = label.toString();
+ }
+ }
+ }
+
+ public BlazeCidrTestConfigurationProducer() {
+ super(BlazeCommandRunConfigurationType.getInstance());
+ }
+
+ @Override
+ protected boolean doSetupConfigFromContext(
+ BlazeCommandRunConfiguration configuration,
+ ConfigurationContext context,
+ Ref<PsiElement> sourceElement) {
+
+ TestTarget testObject = findTestObject(context.getLocation());
+ if (testObject == null) {
+ return false;
+ }
+ sourceElement.set(testObject.element);
+ configuration.setTarget(testObject.label);
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
+ return false;
+ }
+ handlerState.setCommand(BlazeCommandName.TEST);
+
+ ImmutableList.Builder<String> flags = ImmutableList.builder();
+ if (testObject.testFilterArg != null) {
+ flags.add(testObject.testFilterArg);
+ }
+ flags.add(BlazeFlags.TEST_OUTPUT_STREAMED);
+ flags.addAll(handlerState.getBlazeFlags());
+
+ handlerState.setBlazeFlags(flags.build());
+ configuration.setName(
+ String.format(
+ "%s test: %s", Blaze.buildSystemName(configuration.getProject()), testObject.name));
+ return true;
+ }
+
+ @Override
+ protected boolean doIsConfigFromContext(
+ BlazeCommandRunConfiguration configuration, ConfigurationContext context) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
+ return false;
+ }
+ if (!Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)) {
+ return false;
+ }
+ TestTarget testObject = findTestObject(context.getLocation());
+ if (testObject == null) {
+ return false;
+ }
+ List<String> flags = handlerState.getBlazeFlags();
+ return testObject.label.equals(configuration.getTarget())
+ && (testObject.testFilterArg == null || flags.contains(testObject.testFilterArg));
+ }
+
+ @Nullable
+ private static TestTarget findTestObject(Location<?> location) {
+ // Copied from on CidrGoogleTestRunConfigurationProducer::findTestObject.
+
+ // Precedence order (decreasing): class/function, macro, file
+ PsiElement element = location.getPsiElement();
+ PsiElement parent =
+ PsiTreeUtil.getNonStrictParentOfType(element, OCFunctionDefinition.class, OCStruct.class);
+
+ OCStructSymbol parentSymbol;
+ if (parent instanceof OCStruct
+ && ((parentSymbol = ((OCStruct) parent).getSymbol()) != null)
+ && CidrTestUtil.isGoogleTestClass(parentSymbol)) {
+ Couple<String> name = CidrTestUtil.extractGoogleTestName(parentSymbol);
+ if (name != null) {
+ return TestTarget.createFromClassAndMethod(parent, name.first, name.second);
+ }
+ String className = parentSymbol.getQualifiedName().getName();
+ return TestTarget.createFromClass(parent, className);
+ } else if (parent instanceof OCFunctionDefinition) {
+ OCFunctionSymbol symbol = ((OCFunctionDefinition) parent).getSymbol();
+ if (symbol != null) {
+ OCSymbolWithQualifiedName<?> resolvedOwner = symbol.getResolvedOwner();
+ if (resolvedOwner != null) {
+ OCSymbol<?> owner = resolvedOwner.getDefinitionSymbol();
+ if (owner instanceof OCStructSymbol
+ && CidrTestUtil.isGoogleTestClass((OCStructSymbol) owner)) {
+ OCStruct struct = (OCStruct) owner.locateDefinition();
+ Couple<String> name = CidrTestUtil.extractGoogleTestName((OCStructSymbol) owner);
+ if (name != null) {
+ return TestTarget.createFromClassAndMethod(struct, name.first, name.second);
+ }
+ return TestTarget.createFromClass(
+ struct, ((OCStructSymbol) owner).getQualifiedName().getName());
+ }
+ }
+ }
+ }
+
+ // if we're still here, let's test for a macro and, as a last resort, a file.
+ parent = PsiTreeUtil.getNonStrictParentOfType(element, OCMacroCall.class, OCFile.class);
+ if (parent instanceof OCMacroCall) {
+ OCMacroCall gtestMacro = CidrTestUtil.findGoogleTestMacros(parent);
+ if (gtestMacro != null) {
+ List<OCMacroCallArgument> arguments = gtestMacro.getArguments();
+ if (arguments.size() >= 2) {
+ OCMacroCallArgument suiteArg = arguments.get(0);
+ OCMacroCallArgument testArg = arguments.get(1);
+
+ // if the element is the first argument of macro call,
+ // then running entire suite, otherwise only a current test
+ boolean isSuite =
+ isFirstArgument(PsiTreeUtil.getParentOfType(element, OCMacroCallArgument.class))
+ || isFirstArgument(element.getPrevSibling());
+ String suiteName = CidrTestUtil.extractArgumentValue(suiteArg);
+ String testName = CidrTestUtil.extractArgumentValue(testArg);
+ OCStructSymbol symbol =
+ CidrTestUtil.findGoogleTestSymbol(element.getProject(), suiteName, testName);
+ if (symbol != null) {
+ OCStruct targetElement = (OCStruct) symbol.locateDefinition();
+ return TestTarget.createFromClassAndMethod(
+ targetElement, suiteName, isSuite ? null : testName);
+ }
+ }
+ }
+ Couple<String> suite = CidrTestUtil.extractFullSuiteNameFromMacro(parent);
+ if (suite != null) {
+ Collection<OCStructSymbol> res =
+ CidrTestUtil.findGoogleTestSymbolsForSuiteRandomly(
+ element.getProject(), suite.first, true);
+ if (res.size() != 0) {
+ OCStruct struct = (OCStruct) res.iterator().next().locateDefinition();
+ return TestTarget.createFromClassAndMethod(struct, suite.first, null);
+ }
+ }
+ } else if (parent instanceof OCFile) {
+ return TestTarget.createFromFile(parent);
+ }
+ return null;
+ }
+
+ private static boolean isFirstArgument(@Nullable PsiElement element) {
+ OCMacroCall macroCall = PsiTreeUtil.getParentOfType(element, OCMacroCall.class);
+ if (macroCall != null) {
+ List<OCMacroCallArgument> arguments = macroCall.getArguments();
+ return arguments.size() > 0 && arguments.get(0).equals(element);
+ }
+ return false;
+ }
+
+ @Nullable
+ private static Label getCcTestTarget(@Nullable PsiElement element) {
+ if (element == null) {
+ return null;
+ }
+ File file = getContainingFile(element);
+ if (file == null) {
+ return null;
+ }
+ Collection<RuleIdeInfo> rules =
+ TestRuleFinder.getInstance(element.getProject()).testTargetsForSourceFile(file);
+ return TestRuleHeuristic.chooseTestTargetForSourceFile(file, rules, null);
+ }
+
+ private 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;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/sync/BlazeCLionSyncPlugin.java b/clwb/src/com/google/idea/blaze/clwb/sync/BlazeCLionSyncPlugin.java
new file mode 100644
index 0000000..c387715
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/sync/BlazeCLionSyncPlugin.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.sync;
+
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.model.primitives.WorkspaceType;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.sync.BlazeSyncPlugin;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.jetbrains.cidr.cpp.CPPModuleType;
+import java.util.Collection;
+import javax.annotation.Nullable;
+
+class BlazeCLionSyncPlugin extends BlazeSyncPlugin.Adapter {
+
+ @Nullable
+ @Override
+ public WorkspaceType getDefaultWorkspaceType() {
+ return WorkspaceType.C;
+ }
+
+ @Nullable
+ @Override
+ public ModuleType getWorkspaceModuleType(WorkspaceType workspaceType) {
+ if (workspaceType == WorkspaceType.C) {
+ return CPPModuleType.getInstance();
+ }
+ return null;
+ }
+
+ @Override
+ public void updateContentEntries(
+ Project project,
+ BlazeContext context,
+ WorkspaceRoot workspaceRoot,
+ ProjectViewSet projectViewSet,
+ BlazeProjectData blazeProjectData,
+ Collection<ContentEntry> contentEntries) {
+
+ for (ContentEntry entry : contentEntries) {
+ VirtualFile file = entry.getFile();
+ if (file != null) {
+ entry.addSourceFolder(file, false);
+ }
+ }
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeCProjectCreator.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeCProjectCreator.java
new file mode 100644
index 0000000..ed330ca
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeCProjectCreator.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.ide.util.projectWizard.ProjectBuilder;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.components.StorageScheme;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ex.ProjectManagerEx;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.openapi.wm.WindowManager;
+import com.intellij.openapi.wm.ex.IdeFrameEx;
+import com.intellij.openapi.wm.impl.IdeFrameImpl;
+import com.intellij.util.ui.UIUtil;
+import java.io.File;
+import java.io.IOException;
+import javax.annotation.Nullable;
+import javax.swing.SwingUtilities;
+
+class BlazeCProjectCreator {
+ private static final Logger LOG = Logger.getInstance(BlazeCProjectCreator.class);
+
+ private final WizardContext wizardContext;
+ private final ProjectBuilder projectBuilder;
+
+ public BlazeCProjectCreator(WizardContext wizardContext, ProjectBuilder projectBuilder) {
+ this.wizardContext = wizardContext;
+ this.projectBuilder = projectBuilder;
+ }
+
+ @Nullable
+ public Project createFromWizard() {
+ try {
+ return doCreate();
+ } catch (final IOException e) {
+ UIUtil.invokeLaterIfNeeded(
+ () -> Messages.showErrorDialog(e.getMessage(), "Project Initialization Failed"));
+ return null;
+ }
+ }
+
+ @Nullable
+ private Project doCreate() throws IOException {
+ final ProjectManagerEx projectManager = ProjectManagerEx.getInstanceEx();
+ final String projectFilePath = wizardContext.getProjectFileDirectory();
+
+ try {
+ File projectDir = new File(projectFilePath).getParentFile();
+ LOG.assertTrue(
+ projectDir != null,
+ "Cannot create project in '" + projectFilePath + "': no parent file exists");
+ FileUtil.ensureExists(projectDir);
+ if (wizardContext.getProjectStorageFormat() == StorageScheme.DIRECTORY_BASED) {
+ final File ideaDir = new File(projectFilePath, Project.DIRECTORY_STORE_FOLDER);
+ FileUtil.ensureExists(ideaDir);
+ }
+
+ String name = wizardContext.getProjectName();
+ Project newProject = projectBuilder.createProject(name, projectFilePath);
+ if (newProject == null) {
+ return null;
+ }
+
+ if (!ApplicationManager.getApplication().isUnitTestMode()) {
+ newProject.save();
+ }
+
+ if (!projectBuilder.validate(null, newProject)) {
+ return null;
+ }
+
+ projectBuilder.commit(newProject, null, ModulesProvider.EMPTY_MODULES_PROVIDER);
+
+ StartupManager.getInstance(newProject)
+ .registerPostStartupActivity(
+ () -> {
+ // ensure the dialog is shown after all startup activities are done
+ //noinspection SSBasedInspection
+ SwingUtilities.invokeLater(
+ () -> {
+ if (newProject.isDisposed()
+ || ApplicationManager.getApplication().isUnitTestMode()) {
+ return;
+ }
+ ApplicationManager.getApplication()
+ .invokeLater(
+ () -> {
+ if (newProject.isDisposed()) {
+ return;
+ }
+ final ToolWindow toolWindow =
+ ToolWindowManager.getInstance(newProject)
+ .getToolWindow(ToolWindowId.PROJECT_VIEW);
+ if (toolWindow != null) {
+ toolWindow.activate(null);
+ }
+ },
+ ModalityState.NON_MODAL);
+ });
+ });
+
+ ProjectUtil.updateLastProjectLocation(projectFilePath);
+
+ if (WindowManager.getInstance().isFullScreenSupportedInCurrentOS()) {
+ IdeFocusManager instance = IdeFocusManager.findInstance();
+ IdeFrame lastFocusedFrame = instance.getLastFocusedFrame();
+ if (lastFocusedFrame instanceof IdeFrameEx) {
+ boolean fullScreen = ((IdeFrameEx) lastFocusedFrame).isInFullScreen();
+ if (fullScreen) {
+ newProject.putUserData(IdeFrameImpl.SHOULD_OPEN_IN_FULL_SCREEN, Boolean.TRUE);
+ }
+ }
+ }
+
+ projectManager.openProject(newProject);
+
+ if (!ApplicationManager.getApplication().isUnitTestMode()) {
+ newProject.save();
+ }
+ return newProject;
+ } finally {
+ projectBuilder.cleanup();
+ }
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeEditProjectViewImportWizardStep.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeEditProjectViewImportWizardStep.java
new file mode 100644
index 0000000..2998d4a
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeEditProjectViewImportWizardStep.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.google.idea.blaze.base.ui.BlazeValidationResult;
+import com.google.idea.blaze.base.wizard2.BlazeNewProjectBuilder;
+import com.google.idea.blaze.base.wizard2.BlazeProjectCommitException;
+import com.google.idea.blaze.base.wizard2.ui.BlazeEditProjectViewControl;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.openapi.options.ConfigurationException;
+import java.awt.BorderLayout;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import org.jetbrains.annotations.NotNull;
+
+/** Shows the edit project view screen. */
+class BlazeEditProjectViewImportWizardStep extends ProjectImportWizardStep {
+
+ private final JPanel component = new JPanel(new BorderLayout());
+ private BlazeEditProjectViewControl control;
+ private boolean settingsInitialised;
+
+ public BlazeEditProjectViewImportWizardStep(@NotNull WizardContext context) {
+ super(context);
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return component;
+ }
+
+ @Override
+ public void updateStep() {
+ if (!settingsInitialised) {
+ init();
+ } else {
+ control.update(getProjectBuilder());
+ }
+ }
+
+ private void init() {
+ control =
+ new BlazeEditProjectViewControl(getProjectBuilder(), getWizardContext().getDisposable());
+ this.component.add(control.getUiComponent());
+ settingsInitialised = true;
+ }
+
+ @Override
+ public boolean validate() throws ConfigurationException {
+ BlazeValidationResult validationResult = control.validate();
+ if (validationResult.error != null) {
+ throw new ConfigurationException(validationResult.error.getError());
+ }
+ return validationResult.success;
+ }
+
+ @Override
+ public void updateDataModel() {
+ BlazeNewProjectBuilder builder = getProjectBuilder();
+ control.updateBuilder(builder);
+
+ WizardContext wizardContext = getWizardContext();
+ wizardContext.setProjectName(builder.getProjectName());
+ wizardContext.setProjectFileDirectory(builder.getProjectDataDirectory());
+ }
+
+ @Override
+ public void onWizardFinished() throws CommitStepException {
+ try {
+ getProjectBuilder().commit();
+ } catch (BlazeProjectCommitException e) {
+ throw new CommitStepException(e.getMessage());
+ }
+ }
+
+ @Override
+ public String getHelpId() {
+ return "docs/project-views.md";
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeImportProjectAction.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeImportProjectAction.java
new file mode 100644
index 0000000..76148dd
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeImportProjectAction.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.google.idea.blaze.base.settings.Blaze;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+
+class BlazeImportProjectAction extends AnAction {
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ BlazeNewProjectWizard wizard =
+ new BlazeNewProjectWizard() {
+ @Override
+ protected ProjectImportWizardStep[] getSteps(WizardContext context) {
+ return new ProjectImportWizardStep[] {
+ new BlazeSelectWorkspaceImportWizardStep(context),
+ new BlazeSelectBuildSystemBinaryStep(context),
+ new BlazeSelectProjectViewImportWizardStep(context),
+ new BlazeEditProjectViewImportWizardStep(context)
+ };
+ }
+ };
+ if (!wizard.showAndGet()) {
+ return;
+ }
+ BlazeCProjectCreator projectCreator = new BlazeCProjectCreator(wizard.context, wizard.builder);
+ projectCreator.createFromWizard();
+ }
+
+ @Override
+ public void update(AnActionEvent e) {
+ super.update(e);
+ e.getPresentation()
+ .setText(String.format("Import %s Project...", Blaze.defaultBuildSystemName()));
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeNewProjectWizard.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeNewProjectWizard.java
new file mode 100644
index 0000000..d323603
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeNewProjectWizard.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.google.idea.blaze.base.help.BlazeHelpHandler;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.AbstractWizard;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.project.DumbModePermission;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Ref;
+import java.awt.event.ActionListener;
+import javax.annotation.Nullable;
+
+/** Largely copied from AbstractProjectWizard / AddModuleWizard (which aren't in the CLion SDK). */
+abstract class BlazeNewProjectWizard extends AbstractWizard<ProjectImportWizardStep> {
+
+ final WizardContext context;
+ final BlazeProjectImportBuilder builder;
+
+ public BlazeNewProjectWizard() {
+ super("Import Project from " + Blaze.defaultBuildSystemName(), (Project) null);
+
+ builder = new BlazeProjectImportBuilder();
+ context = new WizardContext(null, getDisposable());
+ context.setWizard(this);
+ context.setProjectBuilder(builder);
+ for (ProjectImportWizardStep step : getSteps(context)) {
+ addStep(step);
+ }
+ init();
+ }
+
+ protected abstract ProjectImportWizardStep[] getSteps(WizardContext context);
+
+ @Override
+ protected void helpAction() {
+ doHelpAction();
+ }
+
+ @Override
+ protected void doHelpAction() {
+ String helpId = getHelpID();
+ BlazeHelpHandler helpHandler = BlazeHelpHandler.getInstance();
+ if (helpId != null && helpHandler != null) {
+ helpHandler.handleHelp(helpId);
+ }
+ }
+
+ @Nullable
+ @Override
+ protected String getHelpID() {
+ ProjectImportWizardStep step = getCurrentStepObject();
+ if (step != null) {
+ return step.getHelpId();
+ }
+ return null;
+ }
+
+ // Swallow the escape key
+ @Nullable
+ @Override
+ protected ActionListener createCancelAction() {
+ return null;
+ }
+
+ @Override
+ protected void updateStep() {
+ if (!mySteps.isEmpty()) {
+ getCurrentStepObject().updateStep();
+ }
+ super.updateStep();
+ myIcon.setIcon(null);
+ }
+
+ @Override
+ protected final void doOKAction() {
+ final Ref<Boolean> result = Ref.create(false);
+ DumbService.allowStartingDumbModeInside(
+ DumbModePermission.MAY_START_BACKGROUND,
+ new Runnable() {
+ @Override
+ public void run() {
+ result.set(doFinishAction());
+ }
+ });
+ if (!result.get()) {
+ return;
+ }
+ super.doOKAction();
+ }
+
+ private boolean doFinishAction() {
+ int idx = getCurrentStep();
+ try {
+ do {
+ ProjectImportWizardStep step = mySteps.get(idx);
+ if (step != getCurrentStepObject()) {
+ step.updateStep();
+ }
+ if (!commitStepData(step)) {
+ return false;
+ }
+ try {
+ step._commit(true);
+ } catch (CommitStepException e) {
+ handleCommitException(e);
+ return false;
+ }
+ if (!isLastStep(idx)) {
+ idx = getNextStep(idx);
+ } else {
+ for (ProjectImportWizardStep wizardStep : mySteps) {
+ try {
+ wizardStep.onWizardFinished();
+ } catch (CommitStepException e) {
+ handleCommitException(e);
+ return false;
+ }
+ }
+ break;
+ }
+ } while (true);
+ } finally {
+ myCurrentStep = idx;
+ updateStep();
+ }
+ return true;
+ }
+
+ private boolean commitStepData(ProjectImportWizardStep step) {
+ try {
+ if (!step.validate()) {
+ return false;
+ }
+ } catch (ConfigurationException e) {
+ Messages.showErrorDialog(myContentPanel, e.getMessage(), e.getTitle());
+ return false;
+ }
+ step.updateDataModel();
+ return true;
+ }
+
+ @Override
+ public void doNextAction() {
+ if (!commitStepData(getCurrentStepObject())) {
+ return;
+ }
+ super.doNextAction();
+ }
+
+ private void handleCommitException(CommitStepException e) {
+ String message = e.getMessage();
+ if (message != null) {
+ Messages.showErrorDialog(getCurrentStepComponent(), message);
+ }
+ }
+
+ @Override
+ protected boolean isLastStep() {
+ return isLastStep(getCurrentStep());
+ }
+
+ private boolean isLastStep(int step) {
+ return getNextStep(step) == step;
+ }
+
+ @Override
+ protected int getNextStep(int stepIndex) {
+ int nextIndex = stepIndex + 1;
+ while (nextIndex < mySteps.size()) {
+ ProjectImportWizardStep nextStep = mySteps.get(nextIndex);
+ if (nextStep.isStepVisible()) {
+ return nextIndex;
+ }
+ nextIndex++;
+ }
+ return stepIndex;
+ }
+
+ @Override
+ protected int getPreviousStep(int stepIndex) {
+ int prevIndex = stepIndex - 1;
+ while (prevIndex >= 0) {
+ ProjectImportWizardStep prevStep = mySteps.get(prevIndex);
+ if (prevStep.isStepVisible()) {
+ return prevIndex;
+ }
+ prevIndex--;
+ }
+ return stepIndex;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeProjectImportBuilder.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeProjectImportBuilder.java
new file mode 100644
index 0000000..58ef928
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeProjectImportBuilder.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.wizard2.BlazeNewProjectBuilder;
+import com.intellij.ide.util.projectWizard.ProjectBuilder;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/** Wrapper around a {@link BlazeNewProjectBuilder} to fit into IntelliJ's import framework. */
+class BlazeProjectImportBuilder extends ProjectBuilder {
+ private BlazeNewProjectBuilder builder = new BlazeNewProjectBuilder();
+
+ @Nullable
+ @Override
+ public List<Module> commit(
+ Project project,
+ @Nullable ModifiableModuleModel modifiableModuleModel,
+ ModulesProvider modulesProvider) {
+ builder.commitToProject(project);
+ return ImmutableList.of();
+ }
+
+ public BlazeNewProjectBuilder builder() {
+ return builder;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectBuildSystemBinaryStep.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectBuildSystemBinaryStep.java
new file mode 100644
index 0000000..808fb63
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectBuildSystemBinaryStep.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
+import com.google.idea.blaze.base.settings.BlazeUserSettings;
+import com.google.idea.blaze.base.ui.BlazeValidationResult;
+import com.google.idea.blaze.base.wizard2.ui.SelectBazelBinaryControl;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.openapi.options.ConfigurationException;
+import java.awt.BorderLayout;
+import javax.annotation.Nullable;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import org.jetbrains.annotations.NotNull;
+
+class BlazeSelectBuildSystemBinaryStep extends
+ com.google.idea.blaze.clwb.wizard2.ProjectImportWizardStep {
+
+ private final JPanel component = new JPanel(new BorderLayout());
+ private SelectBazelBinaryControl control;
+ private boolean settingsInitialized = false;
+
+ public BlazeSelectBuildSystemBinaryStep(@NotNull WizardContext context) {
+ super(context);
+ }
+
+ @Override
+ public boolean isStepVisible() {
+ updateStep();
+ if (control.builder.getBuildSystem() != BuildSystem.Bazel) {
+ return false;
+ }
+ String currentBinaryPath = BlazeUserSettings.getInstance().getBazelBinaryPath();
+ return currentBinaryPath == null;
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return component;
+ }
+
+ @Override
+ public void updateStep() {
+ if (!settingsInitialized) {
+ init();
+ }
+ }
+
+ private void init() {
+ control = new SelectBazelBinaryControl(getProjectBuilder());
+ component.add(control.getUiComponent());
+ settingsInitialized = true;
+ }
+
+ @Override
+ public boolean validate() throws ConfigurationException {
+ BlazeValidationResult result = control.validate();
+ if (!result.success) {
+ throw new ConfigurationException(result.error.getError());
+ }
+ return true;
+ }
+
+ @Override
+ public void updateDataModel() {}
+
+ @Override
+ public void onWizardFinished() throws CommitStepException {
+ control.commit();
+ }
+
+ @Nullable
+ @Override
+ public String getHelpId() {
+ return null;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectProjectViewImportWizardStep.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectProjectViewImportWizardStep.java
new file mode 100644
index 0000000..9c99539
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectProjectViewImportWizardStep.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.google.idea.blaze.base.ui.BlazeValidationResult;
+import com.google.idea.blaze.base.wizard2.ui.BlazeSelectProjectViewControl;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.openapi.options.ConfigurationException;
+import java.awt.BorderLayout;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import org.jetbrains.annotations.NotNull;
+
+class BlazeSelectProjectViewImportWizardStep extends ProjectImportWizardStep {
+
+ private final JPanel component = new JPanel(new BorderLayout());
+ private BlazeSelectProjectViewControl control;
+ private boolean settingsInitialised;
+
+ public BlazeSelectProjectViewImportWizardStep(@NotNull WizardContext context) {
+ super(context);
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return component;
+ }
+
+ @Override
+ public void updateStep() {
+ if (!settingsInitialised) {
+ init();
+ } else {
+ control.update(getProjectBuilder());
+ }
+ }
+
+ private void init() {
+ control = new BlazeSelectProjectViewControl(getProjectBuilder());
+ this.component.add(control.getUiComponent());
+ settingsInitialised = true;
+ }
+
+ @Override
+ public boolean validate() throws ConfigurationException {
+ BlazeValidationResult result = control.validate();
+ if (!result.success) {
+ throw new ConfigurationException(result.error.getError());
+ }
+ return true;
+ }
+
+ @Override
+ public void updateDataModel() {
+ control.updateBuilder(getProjectBuilder());
+ }
+
+ @Override
+ public void onWizardFinished() throws CommitStepException {
+ control.commit();
+ }
+
+ @Override
+ public String getHelpId() {
+ return "docs/project-views.md";
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectWorkspaceImportWizardStep.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectWorkspaceImportWizardStep.java
new file mode 100644
index 0000000..2b1666e
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/BlazeSelectWorkspaceImportWizardStep.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.google.idea.blaze.base.ui.BlazeValidationResult;
+import com.google.idea.blaze.base.wizard2.ui.BlazeSelectWorkspaceControl;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.openapi.options.ConfigurationException;
+import java.awt.BorderLayout;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import org.jetbrains.annotations.NotNull;
+
+class BlazeSelectWorkspaceImportWizardStep extends
+ com.google.idea.blaze.clwb.wizard2.ProjectImportWizardStep {
+
+ private final JPanel component = new JPanel(new BorderLayout());
+ private BlazeSelectWorkspaceControl control;
+ private boolean settingsInitialised;
+
+ public BlazeSelectWorkspaceImportWizardStep(@NotNull WizardContext context) {
+ super(context);
+ }
+
+ @Override
+ public JComponent getComponent() {
+ return component;
+ }
+
+ @Override
+ public void updateStep() {
+ if (!settingsInitialised) {
+ init();
+ }
+ }
+
+ private void init() {
+ control = new BlazeSelectWorkspaceControl(getProjectBuilder());
+ this.component.add(control.getUiComponent());
+ settingsInitialised = true;
+ }
+
+ @Override
+ public boolean validate() throws ConfigurationException {
+ BlazeValidationResult result = control.validate();
+ if (!result.success) {
+ throw new ConfigurationException(result.error.getError());
+ }
+ return true;
+ }
+
+ @Override
+ public void updateDataModel() {
+ control.updateBuilder(getProjectBuilder());
+ }
+
+ @Override
+ public void onWizardFinished() throws CommitStepException {
+ control.commit();
+ }
+
+ @Override
+ public String getHelpId() {
+ return "docs/import-project.md";
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/wizard2/ProjectImportWizardStep.java b/clwb/src/com/google/idea/blaze/clwb/wizard2/ProjectImportWizardStep.java
new file mode 100644
index 0000000..392385d
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/wizard2/ProjectImportWizardStep.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.wizard2;
+
+import com.google.idea.blaze.base.wizard2.BlazeNewProjectBuilder;
+import com.intellij.ide.util.projectWizard.ProjectBuilder;
+import com.intellij.ide.util.projectWizard.WizardContext;
+import com.intellij.ide.wizard.CommitStepException;
+import com.intellij.ide.wizard.StepAdapter;
+import com.intellij.openapi.options.ConfigurationException;
+import javax.annotation.Nullable;
+import javax.swing.Icon;
+
+abstract class ProjectImportWizardStep extends StepAdapter {
+ private final WizardContext myContext;
+
+ public ProjectImportWizardStep(WizardContext context) {
+ myContext = context;
+ }
+
+ @Override
+ public Icon getIcon() {
+ return myContext.getStepIcon();
+ }
+
+ protected ProjectBuilder getBuilder() {
+ return myContext.getProjectBuilder();
+ }
+
+ protected WizardContext getWizardContext() {
+ return myContext;
+ }
+
+ @Nullable
+ public abstract String getHelpId();
+
+ public boolean isStepVisible() {
+ return true;
+ }
+
+ /** Update UI from BlazeNewProjectBuilder and WizardContext */
+ public abstract void updateStep();
+
+ public abstract boolean validate() throws ConfigurationException;
+
+ /** Commits data from UI into BlazeNewProjectBuilder and WizardContext */
+ public abstract void updateDataModel();
+
+ public abstract void onWizardFinished() throws CommitStepException;
+
+ protected BlazeNewProjectBuilder getProjectBuilder() {
+ BlazeProjectImportBuilder builder =
+ (BlazeProjectImportBuilder) getWizardContext().getProjectBuilder();
+ assert builder != null;
+ return builder.builder();
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/plugin/ClwbPluginId.java b/clwb/src/com/google/idea/blaze/plugin/ClwbPluginId.java
new file mode 100644
index 0000000..c788fe5
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/plugin/ClwbPluginId.java
@@ -0,0 +1,36 @@
+/*
+ * 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.plugin;
+
+import com.google.idea.blaze.base.bazel.BuildSystemProvider;
+import com.google.idea.blaze.base.plugin.BlazePluginId;
+import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
+
+/** IJwB plugin configuration information. */
+public class ClwbPluginId implements BlazePluginId {
+
+ static final String BLAZE_PLUGIN_ID = "com.google.idea.blaze.clwb";
+ static final String BAZEL_PLUGIN_ID = "com.google.idea.bazel.clwb";
+
+ @Override
+ public String getPluginId() {
+ BuildSystem type = BuildSystemProvider.defaultBuildSystem().buildSystem();
+ if (type == BuildSystem.Blaze) {
+ return BLAZE_PLUGIN_ID;
+ }
+ return BAZEL_PLUGIN_ID;
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/plugin/ClwbProjectSpecificInitializer.java b/clwb/src/com/google/idea/blaze/plugin/ClwbProjectSpecificInitializer.java
new file mode 100644
index 0000000..7be43e4
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/plugin/ClwbProjectSpecificInitializer.java
@@ -0,0 +1,40 @@
+/*
+ * 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.plugin;
+
+import com.intellij.openapi.components.AbstractProjectComponent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.jetbrains.cidr.cpp.cmake.workspace.CMakeWorkspace;
+
+/** Runs on project startup, and customizes CLion UI. */
+public class ClwbProjectSpecificInitializer extends AbstractProjectComponent {
+
+ public ClwbProjectSpecificInitializer(Project project) {
+ super(project);
+ }
+
+ @Override
+ public void projectOpened() {
+ // removes the CMake tool window for blaze projects
+ ToolWindowManager manager = ToolWindowManager.getInstance(myProject);
+ ToolWindow tw = manager.getToolWindow(CMakeWorkspace.TOOLWINDOW_ID);
+ if (tw != null) {
+ tw.setAvailable(false, null);
+ }
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/plugin/ClwbSpecificInitializer.java b/clwb/src/com/google/idea/blaze/plugin/ClwbSpecificInitializer.java
new file mode 100644
index 0000000..4a3445e
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/plugin/ClwbSpecificInitializer.java
@@ -0,0 +1,44 @@
+/*
+ * 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.plugin;
+
+import com.google.idea.blaze.base.plugin.BlazeActionRemover;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.jetbrains.cidr.cpp.cmake.actions.ChangeCMakeProjectContentRootAction;
+import com.jetbrains.cidr.cpp.cmake.actions.DropCMakeCacheAction;
+import com.jetbrains.cidr.cpp.cmake.actions.OpenCMakeSettingsAction;
+import com.jetbrains.cidr.cpp.cmake.actions.ReloadCMakeProjectAction;
+import com.jetbrains.cidr.cpp.cmake.actions.ToggleCMakeAutoReloadAction;
+
+/** Runs on startup. */
+public class ClwbSpecificInitializer extends ApplicationComponent.Adapter {
+
+ @Override
+ public void initComponent() {
+ hideCMakeActions();
+ }
+
+ // The original actions will be visible only on plain IDEA projects.
+ private static void hideCMakeActions() {
+ BlazeActionRemover.hideAction(ChangeCMakeProjectContentRootAction.ID);
+ BlazeActionRemover.hideAction(DropCMakeCacheAction.ID);
+ BlazeActionRemover.hideAction(OpenCMakeSettingsAction.ID);
+ BlazeActionRemover.hideAction(ReloadCMakeProjectAction.ID);
+ BlazeActionRemover.hideAction(ToggleCMakeAutoReloadAction.ID);
+ // 'CMake' > 'Show Generated CMake Files' action
+ BlazeActionRemover.hideAction("CMake.ShowGeneratedDir");
+ }
+}
diff --git a/common/experiments/BUILD b/common/experiments/BUILD
index b15de1f..8e7a91d 100644
--- a/common/experiments/BUILD
+++ b/common/experiments/BUILD
@@ -23,7 +23,7 @@
)
load(
- "//intellij_test:test_defs.bzl",
+ "//testing:test_defs.bzl",
"intellij_unit_test_suite",
)
diff --git a/cpp/BUILD b/cpp/BUILD
index 8b23007..f38d357 100644
--- a/cpp/BUILD
+++ b/cpp/BUILD
@@ -38,7 +38,7 @@
)
load(
- "//intellij_test:test_defs.bzl",
+ "//testing:test_defs.bzl",
"intellij_unit_test_suite",
)
diff --git a/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java b/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
index 925f873..6204439 100644
--- a/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
+++ b/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
@@ -25,8 +25,8 @@
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.ideinfo.CToolchainIdeInfo;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
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.LanguageClass;
import com.google.idea.blaze.base.rulemaps.SourceToRuleMap;
import com.google.idea.blaze.base.scope.BlazeContext;
@@ -52,11 +52,11 @@
final class BlazeConfigurationResolver {
private static final class MapEntry {
- public final Label label;
+ public final RuleKey ruleKey;
public final BlazeResolveConfiguration configuration;
- public MapEntry(Label label, BlazeResolveConfiguration configuration) {
- this.label = label;
+ public MapEntry(RuleKey ruleKey, BlazeResolveConfiguration configuration) {
+ this.ruleKey = ruleKey;
this.configuration = configuration;
}
}
@@ -64,7 +64,8 @@
private static final Logger LOG = Logger.getInstance(BlazeConfigurationResolver.class);
private final Project project;
- private ImmutableMap<Label, BlazeResolveConfiguration> resolveConfigurations = ImmutableMap.of();
+ private ImmutableMap<RuleKey, BlazeResolveConfiguration> resolveConfigurations =
+ ImmutableMap.of();
public BlazeConfigurationResolver(Project project) {
this.project = project;
@@ -72,7 +73,7 @@
public void update(BlazeContext context, BlazeProjectData blazeProjectData) {
WorkspacePathResolver workspacePathResolver = blazeProjectData.workspacePathResolver;
- ImmutableMap<Label, CToolchainIdeInfo> toolchainLookupMap =
+ ImmutableMap<RuleKey, CToolchainIdeInfo> toolchainLookupMap =
BlazeResolveConfiguration.buildToolchainLookupMap(
context, blazeProjectData.ruleMap, blazeProjectData.reverseDependencies);
resolveConfigurations =
@@ -80,15 +81,15 @@
context, blazeProjectData, toolchainLookupMap, workspacePathResolver);
}
- private ImmutableMap<Label, BlazeResolveConfiguration> buildBlazeConfigurationMap(
+ private ImmutableMap<RuleKey, BlazeResolveConfiguration> buildBlazeConfigurationMap(
BlazeContext parentContext,
BlazeProjectData blazeProjectData,
- ImmutableMap<Label, CToolchainIdeInfo> toolchainLookupMap,
+ ImmutableMap<RuleKey, CToolchainIdeInfo> toolchainLookupMap,
WorkspacePathResolver workspacePathResolver) {
// Type specification needed to avoid incorrect type inference during command line build.
return Scope.push(
parentContext,
- (ScopedFunction<ImmutableMap<Label, BlazeResolveConfiguration>>)
+ (ScopedFunction<ImmutableMap<RuleKey, BlazeResolveConfiguration>>)
context -> {
context.push(new TimingScope("Build C configuration map"));
@@ -110,7 +111,7 @@
}
}
- ImmutableMap.Builder<Label, BlazeResolveConfiguration> newResolveConfigurations =
+ ImmutableMap.Builder<RuleKey, BlazeResolveConfiguration> newResolveConfigurations =
ImmutableMap.builder();
List<MapEntry> mapEntries;
try {
@@ -125,7 +126,7 @@
for (MapEntry mapEntry : mapEntries) {
// Skip over labels that don't have C configuration data.
if (mapEntry != null) {
- newResolveConfigurations.put(mapEntry.label, mapEntry.configuration);
+ newResolveConfigurations.put(mapEntry.ruleKey, mapEntry.configuration);
}
}
return newResolveConfigurations.build();
@@ -139,27 +140,28 @@
@Nullable
private MapEntry createResolveConfiguration(
RuleIdeInfo rule,
- ImmutableMap<Label, CToolchainIdeInfo> toolchainLookupMap,
+ ImmutableMap<RuleKey, CToolchainIdeInfo> toolchainLookupMap,
ConcurrentMap<CToolchainIdeInfo, File> compilerWrapperCache,
WorkspacePathResolver workspacePathResolver,
BlazeProjectData blazeProjectData) {
- Label label = rule.label;
- LOG.info("Resolving " + label.toString());
- CToolchainIdeInfo toolchainIdeInfo = toolchainLookupMap.get(label);
+ RuleKey ruleKey = rule.key;
+ LOG.info("Resolving " + ruleKey);
+
+ CToolchainIdeInfo toolchainIdeInfo = toolchainLookupMap.get(ruleKey);
if (toolchainIdeInfo != null) {
File compilerWrapper =
findOrCreateCompilerWrapperScript(
- compilerWrapperCache, toolchainIdeInfo, workspacePathResolver, rule.label);
+ compilerWrapperCache, toolchainIdeInfo, workspacePathResolver, ruleKey);
if (compilerWrapper != null) {
BlazeResolveConfiguration config =
BlazeResolveConfiguration.createConfigurationForTarget(
project,
workspacePathResolver,
- blazeProjectData.ruleMap.get(label),
+ blazeProjectData.ruleMap.get(ruleKey),
toolchainIdeInfo,
compilerWrapper);
if (config != null) {
- return new MapEntry(label, config);
+ return new MapEntry(ruleKey, config);
}
}
}
@@ -171,7 +173,7 @@
Map<CToolchainIdeInfo, File> compilerWrapperCache,
CToolchainIdeInfo toolchainIdeInfo,
WorkspacePathResolver workspacePathResolver,
- Label label) {
+ RuleKey ruleKey) {
File compilerWrapper = compilerWrapperCache.get(toolchainIdeInfo);
if (compilerWrapper == null) {
File cppExecutable = toolchainIdeInfo.cppExecutable.getAbsoluteOrRelativeFile();
@@ -182,7 +184,7 @@
String errorMessage =
String.format(
"Unable to find compiler executable: %s for rule %s",
- toolchainIdeInfo.cppExecutable.toString(), label.toString());
+ toolchainIdeInfo.cppExecutable.toString(), ruleKey);
LOG.warn(errorMessage);
compilerWrapper = null;
} else {
@@ -251,9 +253,9 @@
@Nullable
public OCResolveConfiguration getConfigurationForFile(VirtualFile sourceFile) {
SourceToRuleMap sourceToRuleMap = SourceToRuleMap.getInstance(project);
- List<Label> targetsForSourceFile =
+ List<RuleKey> targetsForSourceFile =
Lists.newArrayList(
- sourceToRuleMap.getTargetsForSourceFile(VfsUtilCore.virtualToIoFile(sourceFile)));
+ sourceToRuleMap.getRulesForSourceFile(VfsUtilCore.virtualToIoFile(sourceFile)));
if (targetsForSourceFile.isEmpty()) {
return null;
}
@@ -262,10 +264,10 @@
// we can't possibly show how it will be interpreted in both contexts at the same time
// in the IDE, so just pick the first target after we sort.
targetsForSourceFile.sort((o1, o2) -> o1.toString().compareTo(o2.toString()));
- Label target = Iterables.getFirst(targetsForSourceFile, null);
- assert (target != null);
+ RuleKey ruleKey = Iterables.getFirst(targetsForSourceFile, null);
+ assert (ruleKey != null);
- return resolveConfigurations.get(target);
+ return resolveConfigurations.get(ruleKey);
}
public List<? extends OCResolveConfiguration> getAllConfigurations() {
diff --git a/cpp/src/com/google/idea/blaze/cpp/BlazeResolveConfigurationTemporaryBase.java b/cpp/src/com/google/idea/blaze/cpp/BlazeResolveConfigurationTemporaryBase.java
index a710707..ef7b9c0 100644
--- a/cpp/src/com/google/idea/blaze/cpp/BlazeResolveConfigurationTemporaryBase.java
+++ b/cpp/src/com/google/idea/blaze/cpp/BlazeResolveConfigurationTemporaryBase.java
@@ -25,9 +25,9 @@
import com.google.idea.blaze.base.ideinfo.CRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.CToolchainIdeInfo;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.RuleMap;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
-import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.Scope;
import com.google.idea.blaze.base.scope.scopes.TimingScope;
@@ -72,7 +72,7 @@
/* project, label are protected instead of private just so v145 can access */
protected final Project project;
- protected final Label label;
+ protected final RuleKey ruleKey;
private final ImmutableList<HeadersSearchRoot> cLibraryIncludeRoots;
private final ImmutableList<HeadersSearchRoot> cppLibraryIncludeRoots;
@@ -120,7 +120,7 @@
return new BlazeResolveConfiguration(
project,
workspacePathResolver,
- ruleIdeInfo.label,
+ ruleIdeInfo.key,
systemIncludesBuilder.build(),
systemIncludesBuilder.build(),
userQuoteIncludesBuilder.build(),
@@ -134,30 +134,31 @@
cppFlagsBuilder.build());
}
- public static ImmutableMap<Label, CToolchainIdeInfo> buildToolchainLookupMap(
- BlazeContext context, RuleMap ruleMap, ImmutableMultimap<Label, Label> reverseDependencies) {
+ public static ImmutableMap<RuleKey, CToolchainIdeInfo> buildToolchainLookupMap(
+ BlazeContext context,
+ RuleMap ruleMap,
+ ImmutableMultimap<RuleKey, RuleKey> reverseDependencies) {
return Scope.push(
context,
childContext -> {
childContext.push(new TimingScope("Build toolchain lookup map"));
- List<Label> seeds = Lists.newArrayList();
+ List<RuleKey> seeds = Lists.newArrayList();
for (RuleIdeInfo rule : ruleMap.rules()) {
- Label label = rule.label;
CToolchainIdeInfo cToolchainIdeInfo = rule.cToolchainIdeInfo;
if (cToolchainIdeInfo != null) {
- seeds.add(label);
+ seeds.add(rule.key);
}
}
- Map<Label, CToolchainIdeInfo> lookupTable = Maps.newHashMap();
- for (Label seed : seeds) {
+ Map<RuleKey, CToolchainIdeInfo> lookupTable = Maps.newHashMap();
+ for (RuleKey seed : seeds) {
CToolchainIdeInfo toolchainInfo = ruleMap.get(seed).cToolchainIdeInfo;
LOG.assertTrue(toolchainInfo != null);
- List<Label> worklist = Lists.newArrayList(reverseDependencies.get(seed));
+ List<RuleKey> worklist = Lists.newArrayList(reverseDependencies.get(seed));
while (!worklist.isEmpty()) {
// We should never see a label depend on two different toolchains.
- Label l = worklist.remove(0);
+ RuleKey l = worklist.remove(0);
CToolchainIdeInfo previousValue = lookupTable.putIfAbsent(l, toolchainInfo);
// Don't propagate the toolchain twice.
if (previousValue == null) {
@@ -174,7 +175,7 @@
public BlazeResolveConfigurationTemporaryBase(
Project project,
WorkspacePathResolver workspacePathResolver,
- Label label,
+ RuleKey ruleKey,
ImmutableCollection<ExecutionRootPath> cSystemIncludeDirs,
ImmutableCollection<ExecutionRootPath> cppSystemIncludeDirs,
ImmutableCollection<ExecutionRootPath> quoteIncludeDirs,
@@ -188,7 +189,7 @@
ImmutableList<String> cppCompilerFlags) {
this.workspacePathResolver = workspacePathResolver;
this.project = project;
- this.label = label;
+ this.ruleKey = ruleKey;
ImmutableList.Builder<HeadersSearchRoot> cIncludeRootsBuilder = ImmutableList.builder();
collectHeaderRoots(cIncludeRootsBuilder, cIncludeDirs, true /* isUserHeader */);
@@ -220,7 +221,7 @@
@Override
public String getDisplayName(boolean shorten) {
- return label.toString();
+ return ruleKey.toString();
}
@Nullable
@@ -355,8 +356,8 @@
@Override
public int hashCode() {
- // There should only be one configuration per label.
- return Objects.hash(label);
+ // There should only be one configuration per target.
+ return Objects.hash(ruleKey);
}
@Override
diff --git a/cpp/src/com/google/idea/blaze/cpp/versioned/v145/BlazeResolveConfiguration.java b/cpp/src/com/google/idea/blaze/cpp/versioned/v145/BlazeResolveConfiguration.java
index 7704f4f..9671707 100644
--- a/cpp/src/com/google/idea/blaze/cpp/versioned/v145/BlazeResolveConfiguration.java
+++ b/cpp/src/com/google/idea/blaze/cpp/versioned/v145/BlazeResolveConfiguration.java
@@ -18,8 +18,8 @@
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
-import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.intellij.openapi.project.Project;
import com.jetbrains.cidr.execution.CidrBuildTarget;
@@ -36,7 +36,7 @@
public BlazeResolveConfiguration(
Project project,
WorkspacePathResolver workspacePathResolver,
- Label label,
+ RuleKey ruleKey,
ImmutableCollection<ExecutionRootPath> cSystemIncludeDirs,
ImmutableCollection<ExecutionRootPath> cppSystemIncludeDirs,
ImmutableCollection<ExecutionRootPath> quoteIncludeDirs,
@@ -51,7 +51,7 @@
super(
project,
workspacePathResolver,
- label,
+ ruleKey,
cSystemIncludeDirs,
cppSystemIncludeDirs,
quoteIncludeDirs,
@@ -71,7 +71,7 @@
return new CidrBuildTargetWithConfigurations() {
@Override
public String getName() {
- return label.toString();
+ return ruleKey.toString();
}
@Override
diff --git a/cpp/src/com/google/idea/blaze/cpp/versioned/v162/BlazeResolveConfiguration.java b/cpp/src/com/google/idea/blaze/cpp/versioned/v162/BlazeResolveConfiguration.java
index c5c5e86..8935576 100644
--- a/cpp/src/com/google/idea/blaze/cpp/versioned/v162/BlazeResolveConfiguration.java
+++ b/cpp/src/com/google/idea/blaze/cpp/versioned/v162/BlazeResolveConfiguration.java
@@ -18,20 +18,18 @@
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
-import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolver;
import com.intellij.openapi.project.Project;
-import com.jetbrains.cidr.modulemap.ModuleMapModules;
import java.io.File;
-import org.jetbrains.annotations.NotNull;
final class BlazeResolveConfiguration extends BlazeResolveConfigurationTemporaryBase {
public BlazeResolveConfiguration(
Project project,
WorkspacePathResolver workspacePathResolver,
- Label label,
+ RuleKey ruleKey,
ImmutableCollection<ExecutionRootPath> cSystemIncludeDirs,
ImmutableCollection<ExecutionRootPath> cppSystemIncludeDirs,
ImmutableCollection<ExecutionRootPath> quoteIncludeDirs,
@@ -46,7 +44,7 @@
super(
project,
workspacePathResolver,
- label,
+ ruleKey,
cSystemIncludeDirs,
cppSystemIncludeDirs,
quoteIncludeDirs,
@@ -59,10 +57,4 @@
cCompilerFlags,
cppCompilerFlags);
}
-
- @NotNull
- @Override
- public ModuleMapModules getModules() {
- return ModuleMapModules.Companion.getEMPTY();
- }
}
diff --git a/ijwb/.gitignore b/ijwb/.gitignore
deleted file mode 100644
index bec2fed..0000000
--- a/ijwb/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-.idea/workspace.xml
-.idea/tasks.xml
-out
-bazel-bin
-bazel-out
-bazel-genfiles
-bazel-testlogs
-bazel-blaze
diff --git a/ijwb/.bazelproject b/ijwb/ijwb.bazelproject
similarity index 87%
rename from ijwb/.bazelproject
rename to ijwb/ijwb.bazelproject
index f066e1b..e8fc755 100644
--- a/ijwb/.bazelproject
+++ b/ijwb/ijwb.bazelproject
@@ -1,9 +1,8 @@
directories:
.
-aswb
- -aswb-google3
-clwb
- -blaze-cpp
+ -cpp
targets:
//ijwb:ijwb_bazel
diff --git a/ijwb/src/META-INF/ijwb_bazel.xml b/ijwb/src/META-INF/ijwb_bazel.xml
index 2068ad9..0c72d38 100644
--- a/ijwb/src/META-INF/ijwb_bazel.xml
+++ b/ijwb/src/META-INF/ijwb_bazel.xml
@@ -23,7 +23,7 @@
<ul>
<li>Import BUILD files into the IDE.</li>
<li>BUILD file custom language support.</li>
- <li>Support for blaze run configurations for certain rule classes.</li>
+ <li>Support for Bazel run configurations for certain rule classes.</li>
</ul>
Usage instructions at <a href="http://ij.bazel.io">ij.bazel.io</a>
diff --git a/ijwb/src/com/google/idea/blaze/ijwb/android/BlazeAndroidLiteJavaSyncAugmenter.java b/ijwb/src/com/google/idea/blaze/ijwb/android/BlazeAndroidLiteJavaSyncAugmenter.java
index 0d864b8..8aaa2b5 100644
--- a/ijwb/src/com/google/idea/blaze/ijwb/android/BlazeAndroidLiteJavaSyncAugmenter.java
+++ b/ijwb/src/com/google/idea/blaze/ijwb/android/BlazeAndroidLiteJavaSyncAugmenter.java
@@ -43,12 +43,12 @@
// Add R.java jars
LibraryArtifact resourceJar = androidRuleIdeInfo.resourceJar;
if (resourceJar != null) {
- jars.add(new BlazeJarLibrary(resourceJar, rule.label));
+ jars.add(new BlazeJarLibrary(resourceJar, rule.key));
}
LibraryArtifact idlJar = androidRuleIdeInfo.idlJar;
if (idlJar != null) {
- genJars.add(new BlazeJarLibrary(idlJar, rule.label));
+ genJars.add(new BlazeJarLibrary(idlJar, rule.key));
}
}
}
diff --git a/ijwb/src/com/google/idea/blaze/ijwb/typescript/BlazeTypescriptSyncPlugin.java b/ijwb/src/com/google/idea/blaze/ijwb/typescript/BlazeTypescriptSyncPlugin.java
index 3659a42..726b50e 100644
--- a/ijwb/src/com/google/idea/blaze/ijwb/typescript/BlazeTypescriptSyncPlugin.java
+++ b/ijwb/src/com/google/idea/blaze/ijwb/typescript/BlazeTypescriptSyncPlugin.java
@@ -22,9 +22,9 @@
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.ideinfo.RuleMap;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
@@ -40,6 +40,7 @@
import com.google.idea.blaze.base.settings.Blaze;
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;
@@ -73,6 +74,7 @@
BlazeRoots blazeRoots,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
+ ArtifactLocationDecoder artifactLocationDecoder,
RuleMap ruleMap,
SyncState.Builder syncStateBuilder,
@Nullable SyncState previousSyncState) {
diff --git a/intellij_test/src/com/google/idea/blaze/base/suite/TestAggregator.java b/intellij_test/src/com/google/idea/blaze/base/suite/TestAggregator.java
deleted file mode 100644
index dbae268..0000000
--- a/intellij_test/src/com/google/idea/blaze/base/suite/TestAggregator.java
+++ /dev/null
@@ -1,30 +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.suite;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Used to denote a class which shouldn't be treated as a test by {@link TestClassFinder}, which
- * searches for all test classes in the classpath matching a pattern.<br>
- * This is useful to prevent infinite loops.
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE})
-public @interface TestAggregator {}
diff --git a/intellij_test/src/com/google/idea/blaze/base/suite/TestAll.java b/intellij_test/src/com/google/idea/blaze/base/suite/TestAll.java
deleted file mode 100644
index b40fafe..0000000
--- a/intellij_test/src/com/google/idea/blaze/base/suite/TestAll.java
+++ /dev/null
@@ -1,222 +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.suite;
-
-import com.intellij.TestCaseLoader;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.testFramework.TeamCityLogger;
-import com.intellij.testFramework.TestLoggerFactory;
-import com.intellij.testFramework.TestRunnerUtil;
-import com.intellij.util.ArrayUtil;
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import javax.annotation.Nullable;
-import junit.framework.JUnit4TestAdapter;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestResult;
-import junit.framework.TestSuite;
-
-/** A cut-down version of {@link com.intellij.TestAll} which supports test classes inside jars. */
-@TestAggregator
-public class TestAll implements Test {
-
- static {
- Logger.setFactory(TestLoggerFactory.class);
- }
-
- private final TestCaseLoader testCaseLoader;
-
- public TestAll(String packageRoot) throws Throwable {
- this(packageRoot, getClassRoots());
- }
-
- public TestAll(String packageRoot, String... classRoots)
- throws IOException, ClassNotFoundException {
- testCaseLoader = new TestCaseLoader("");
- fillTestCases(testCaseLoader, packageRoot, classRoots);
- }
-
- public static String[] getClassRoots() {
- final ClassLoader loader = TestAll.class.getClassLoader();
- if (loader instanceof URLClassLoader) {
- return getClassRoots(((URLClassLoader) loader).getURLs());
- }
- final Class<? extends ClassLoader> loaderClass = loader.getClass();
- if (loaderClass.getName().equals("com.intellij.util.lang.UrlClassLoader")) {
- try {
- final Method declaredMethod = loaderClass.getDeclaredMethod("getBaseUrls");
- final List<URL> urls = (List<URL>) declaredMethod.invoke(loader);
- return getClassRoots(urls.toArray(new URL[urls.size()]));
- } catch (Throwable ignore) {
- // Do nothing
- }
- }
- return System.getProperty("java.class.path").split(File.pathSeparator);
- }
-
- private static String[] getClassRoots(URL[] urls) {
- return Arrays.stream(urls)
- .map(VfsUtilCore::convertFromUrl)
- .map(VfsUtilCore::urlToPath)
- .toArray(String[]::new);
- }
-
- private static boolean isIntellijPlatformJar(String classRoot) {
- return classRoot.contains("intellij-platform-sdk");
- }
-
- public static void fillTestCases(
- TestCaseLoader testCaseLoader, String packageRoot, String... classRoots) throws IOException {
- long before = System.currentTimeMillis();
- for (String classRoot : classRoots) {
- if (isIntellijPlatformJar(classRoot)) {
- continue;
- }
- int oldCount = testCaseLoader.getClasses().size();
- File classRootFile = new File(FileUtil.toSystemDependentName(classRoot));
- Collection<String> classes = TestClassFinder.findTestClasses(classRootFile, packageRoot);
- testCaseLoader.loadTestCases(classRootFile.getName(), classes);
- int newCount = testCaseLoader.getClasses().size();
- if (newCount != oldCount) {
- System.out.println(
- "Loaded " + (newCount - oldCount) + " tests from class root " + classRoot);
- }
- }
-
- if (testCaseLoader.getClasses().size() == 1) {
- testCaseLoader.clearClasses();
- }
- long after = System.currentTimeMillis();
-
- String message =
- "Number of test classes found: "
- + testCaseLoader.getClasses().size()
- + " time to load: "
- + (after - before) / 1000
- + "s.";
- System.out.println(message);
- log(message);
- }
-
- @Override
- public int countTestCases() {
- int count = 0;
- for (Object aClass : testCaseLoader.getClasses()) {
- Test test = getTest((Class) aClass);
- if (test != null) {
- count += test.countTestCases();
- }
- }
- return count;
- }
-
- @Override
- public void run(final TestResult testResult) {
- List<Class> classes = testCaseLoader.getClasses();
- for (Class<?> aClass : classes) {
- runTest(testResult, aClass);
- if (testResult.shouldStop()) {
- break;
- }
- }
- }
-
- private void runTest(final TestResult testResult, Class testCaseClass) {
- Test test = getTest(testCaseClass);
- if (test == null) {
- return;
- }
-
- try {
- test.run(testResult);
- } catch (Throwable t) {
- testResult.addError(test, t);
- }
- }
-
- @Nullable
- private static Test getTest(final Class<?> testCaseClass) {
- try {
- if ((testCaseClass.getModifiers() & Modifier.PUBLIC) == 0) {
- return null;
- }
- if (testCaseClass.isAnnotationPresent(TestAggregator.class)) {
- // prevent infinite loops in 'countTestCases'
- return null;
- }
-
- Method suiteMethod = safeFindMethod(testCaseClass, "suite");
- if (suiteMethod != null) {
- return (Test) suiteMethod.invoke(null, (Object[]) ArrayUtil.EMPTY_CLASS_ARRAY);
- }
-
- if (TestRunnerUtil.isJUnit4TestClass(testCaseClass)) {
- return new JUnit4TestAdapter(testCaseClass);
- }
-
- final int[] testsCount = {0};
- TestSuite suite =
- new TestSuite(testCaseClass) {
- @Override
- public void addTest(Test test) {
- if (!(test instanceof TestCase)) {
- doAddTest(test);
- } else {
- String name = ((TestCase) test).getName();
- if ("warning".equals(name)) {
- return; // Mute TestSuite's "no tests found" warning
- }
- doAddTest(test);
- }
- }
-
- private void doAddTest(Test test) {
- testsCount[0]++;
- super.addTest(test);
- }
- };
-
- return testsCount[0] > 0 ? suite : null;
- } catch (Throwable t) {
- System.err.println("Failed to load test: " + testCaseClass.getName());
- t.printStackTrace(System.err);
- return null;
- }
- }
-
- @Nullable
- private static Method safeFindMethod(Class<?> klass, String name) {
- try {
- return klass.getMethod(name);
- } catch (NoSuchMethodException e) {
- return null;
- }
- }
-
- private static void log(String message) {
- TeamCityLogger.info(message);
- }
-}
diff --git a/intellij_test/src/com/google/idea/blaze/base/suite/TestClassFinder.java b/intellij_test/src/com/google/idea/blaze/base/suite/TestClassFinder.java
deleted file mode 100644
index 40633ed..0000000
--- a/intellij_test/src/com/google/idea/blaze/base/suite/TestClassFinder.java
+++ /dev/null
@@ -1,76 +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.suite;
-
-import com.google.common.collect.Sets;
-import com.intellij.ClassFinder;
-import com.intellij.openapi.util.text.StringUtil;
-import java.io.File;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.SortedSet;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/** Finds all valid test classes inside a given directory or jar. */
-@TestAggregator
-public class TestClassFinder {
-
- private static final String CLASS_EXTENSION = ".class";
-
- /** Returns all top-level test classes underneath the specified classpath and package roots. */
- public static SortedSet<String> findTestClasses(File classRootFile, String packageRoot)
- throws IOException {
- if (isJar(classRootFile.getPath())) {
- return findTestClassesInJar(classRootFile, packageRoot);
- }
- ClassFinder finder = new ClassFinder(classRootFile, packageRoot, true);
- return Sets.newTreeSet(finder.getClasses());
- }
-
- private static SortedSet<String> findTestClassesInJar(File classPathRoot, String packageRoot)
- throws IOException {
- packageRoot = packageRoot.replace('.', File.separatorChar);
- SortedSet<String> classNames = Sets.newTreeSet();
- ZipFile zipFile = new ZipFile(classPathRoot.getPath());
- if (!packageRoot.isEmpty() && zipFile.getEntry(packageRoot) == null) {
- return Sets.newTreeSet();
- }
- Enumeration<? extends ZipEntry> entries = zipFile.entries();
- while (entries.hasMoreElements()) {
- String entryName = entries.nextElement().getName();
- if (entryName.endsWith(CLASS_EXTENSION)
- && isTopLevelClass(entryName)
- && entryName.startsWith(packageRoot)) {
- classNames.add(getClassName(entryName));
- }
- }
- return classNames;
- }
-
- private static boolean isJar(String filePath) {
- return filePath.endsWith(".jar");
- }
-
- private static boolean isTopLevelClass(String fileName) {
- return fileName.indexOf('$') < 0;
- }
-
- /** Given the absolute path of a class file, return the class name. */
- private static String getClassName(String className) {
- return StringUtil.trimEnd(className, CLASS_EXTENSION).replace(File.separatorChar, '.');
- }
-}
diff --git a/intellij_test/src/com/google/idea/blaze/base/suite/TestSuiteBuilder.java b/intellij_test/src/com/google/idea/blaze/base/suite/TestSuiteBuilder.java
deleted file mode 100644
index 9d918a1..0000000
--- a/intellij_test/src/com/google/idea/blaze/base/suite/TestSuiteBuilder.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.base.suite;
-
-import com.google.common.base.Strings;
-import com.google.idea.blaze.base.BlazeTestSystemProperties;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import org.junit.runner.RunWith;
-import org.junit.runners.AllTests;
-
-/** Simple JUnit3 style test suite builder. */
-@TestAggregator
-@RunWith(AllTests.class)
-public class TestSuiteBuilder {
- public static Test suite() throws Throwable {
-
- BlazeTestSystemProperties.configureSystemProperties();
-
- String packageRoot = System.getProperty("idea.test.package.root");
- packageRoot = Strings.nullToEmpty(packageRoot);
-
- TestSuite suite = new TestSuite();
- suite.addTest(new TestAll(packageRoot));
- return suite;
- }
-}
diff --git a/intellij_test/test_defs.bzl b/intellij_test/test_defs.bzl
deleted file mode 100644
index 52205c4..0000000
--- a/intellij_test/test_defs.bzl
+++ /dev/null
@@ -1,114 +0,0 @@
-"""Custom rule for creating IntelliJ plugin tests.
-"""
-
-def intellij_unit_test_suite(name, srcs, test_package_root, **kwargs):
- """Creates a java_test rule comprising all valid test classes in the specified srcs.
-
- Args:
- name: name of this rule.
- srcs: the test classes.
- test_package_root: only tests under this package root will be run.
- **kwargs: Any other args to be passed to the java_test.
- """
- test_srcs = [test for test in srcs if test.endswith("Test.java")]
- test_classes = [_get_test_class(test_src, test_package_root) for test_src in test_srcs]
- suite_class_name = name + "TestSuite"
- suite_class = test_package_root + "." + suite_class_name
- _generate_test_suite(
- name = suite_class_name,
- test_package_root = test_package_root,
- test_classes = test_classes,
- )
- native.java_test(
- name = name,
- srcs = srcs + [suite_class_name],
- test_class = suite_class,
- **kwargs)
-
-def _generate_test_suite(name, test_package_root, test_classes):
- """Generates a JUnit test suite pulling in all the referenced classes."""
- lines = []
- lines.append("package %s;" % test_package_root)
- lines.append("")
- lines.append("import org.junit.runner.RunWith;")
- lines.append("import org.junit.runners.Suite;")
- lines.append("")
- for test_class in test_classes:
- lines.append("import %s;" % test_class)
- lines.append("")
- lines.append("@RunWith(Suite.class)")
- lines.append("@Suite.SuiteClasses({")
- for test_class in test_classes:
- lines.append(" %s.class," % test_class.split(".")[-1])
- lines.append("})")
- lines.append("class %s {}" % name)
-
- contents = "\\n".join(lines)
- native.genrule(
- name = name,
- cmd = "printf '%s' > $@" % contents,
- outs = [name + ".java"],
- )
-
-
-def _get_test_class(test_src, test_package_root):
- """Returns the test class of the source relative to the given root."""
- temp = test_src[:-5]
- temp = temp.replace("/", ".")
- i = temp.rfind(test_package_root)
- if i < 0:
- fail("Test source '%s' not under package root '%s'" % (test_src, test_package_root))
- test_class = temp[i:]
- return test_class
-
-def intellij_integration_test_suite(
- name,
- srcs,
- test_package_root,
- deps,
- runtime_deps = [],
- platform_prefix="Idea",
- required_plugins=None,
- **kwargs):
- """Creates a java_test rule comprising all valid test classes in the specified srcs.
-
- Args:
- name: name of this rule.
- srcs: the test classes.
- test_package_root: only tests under this package root will be run.
- deps: the required deps.
- runtime_deps: the required runtime_deps.
- platform_prefix: Specifies the JetBrains product these tests are run against. Examples are
- 'Idea' (IJ CE), 'idea' (IJ UE), 'CLion', 'AndroidStudio'. See
- com.intellij.util.PlatformUtils for other options.
- required_plugins: optional comma-separated list of plugin IDs. Integration tests will fail if
- these plugins aren't loaded at runtime.
- **kwargs: Any other args to be passed to the java_test.
- """
-
- runtime_deps = list(runtime_deps)
- runtime_deps.extend([
- "//intellij_test:lib",
- "//intellij_platform_sdk:bundled_plugins",
- "//third_party:jdk8_tools",
- ])
-
- jvm_flags = [
- "-Didea.classpath.index.enabled=false",
- "-Djava.awt.headless=true",
- "-Didea.platform.prefix=" + platform_prefix,
- "-Didea.test.package.root=" + test_package_root,
- ]
-
- if required_plugins:
- jvm_flags.append("-Didea.required.plugins.id=" + required_plugins)
-
- native.java_test(
- name = name,
- srcs = srcs,
- deps = deps,
- runtime_deps = runtime_deps,
- size = "medium",
- jvm_flags = jvm_flags,
- test_class = "com.google.idea.blaze.base.suite.TestSuiteBuilder",
- **kwargs)
diff --git a/java/BUILD b/java/BUILD
index 4ba94eb..2655b20 100644
--- a/java/BUILD
+++ b/java/BUILD
@@ -52,7 +52,7 @@
)
load(
- "//intellij_test:test_defs.bzl",
+ "//testing:test_defs.bzl",
"intellij_integration_test_suite",
"intellij_unit_test_suite",
)
@@ -89,5 +89,6 @@
"//base:unit_test_utils",
"//intellij_platform_sdk:plugin_api_for_tests",
"@jsr305_annotations//jar",
+ "@junit//jar",
],
)
diff --git a/java/src/META-INF/blaze-java.xml b/java/src/META-INF/blaze-java.xml
index 321e5e4..b2ae955 100644
--- a/java/src/META-INF/blaze-java.xml
+++ b/java/src/META-INF/blaze-java.xml
@@ -37,6 +37,15 @@
<add-to-group group-id="Blaze.ProjectViewPopupMenu"/>
</action>
+ <group>
+ <action class="com.google.idea.blaze.java.libraries.DetachAllSourceJarsAction"
+ id="Blaze.DetachAllSourceJars"
+ text="Detach All Blaze Source Jars">
+ </action>
+ <separator/>
+ <add-to-group group-id="Blaze.MainMenuActionGroup" relative-to-action="Blaze.EditProjectView" anchor="before"/>
+ </group>
+
<!-- IntelliJ specific actions -->
<action id="Blaze.ImportProject2" class="com.google.idea.blaze.java.wizard2.BlazeImportProjectAction" icon="BlazeIcons.Blaze">
@@ -52,11 +61,12 @@
<SyncPlugin implementation="com.google.idea.blaze.java.sync.BlazeJavaSyncPlugin"/>
<PsiFileProvider implementation="com.google.idea.blaze.java.psi.JavaPsiFileProvider" />
<BlazeCommandRunConfigurationHandlerProvider implementation="com.google.idea.blaze.java.run.BlazeJavaRunConfigurationHandlerProvider"/>
- <RuleConfigurationFactory implementation="com.google.idea.blaze.java.run.BlazeJavaRuleConfigurationFactory"/>
- <RuleConfigurationFactory implementation="com.google.idea.blaze.java.run.BlazeJavaTestRuleConfigurationFactory"/>
+ <RunConfigurationFactory implementation="com.google.idea.blaze.java.run.BlazeJavaRunConfigurationFactory"/>
+ <RunConfigurationFactory implementation="com.google.idea.blaze.java.run.BlazeJavaTestRunConfigurationFactory"/>
<BlazeUserSettingsContributor implementation="com.google.idea.blaze.java.settings.BlazeJavaUserSettingsContributor$BlazeJavaUserSettingsProvider"/>
<FileCache implementation="com.google.idea.blaze.java.libraries.JarCache$FileCacheAdapter"/>
<PrefetchFileSource implementation="com.google.idea.blaze.java.sync.JavaPrefetchFileSource"/>
+ <SyncListener implementation="com.google.idea.blaze.java.syncstatus.SyncStatusHelper$UpdateSyncStatusMap"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
@@ -87,6 +97,7 @@
<attachSourcesProvider implementation="com.google.idea.blaze.java.libraries.AddLibraryRuleDirectoryToProjectViewAttachSourcesProvider"/>
<attachSourcesProvider implementation="com.google.idea.blaze.java.libraries.BlazeAttachSourceProvider"/>
<applicationService serviceImplementation="com.google.idea.blaze.java.settings.BlazeJavaUserSettings"/>
+ <projectService serviceImplementation="com.google.idea.blaze.java.syncstatus.SyncStatusHelper"/>
</extensions>
<extensionPoints>
diff --git a/java/src/com/google/idea/blaze/java/libraries/AddLibraryRuleDirectoryToProjectViewAction.java b/java/src/com/google/idea/blaze/java/libraries/AddLibraryRuleDirectoryToProjectViewAction.java
index ac34691..1bf26e7 100644
--- a/java/src/com/google/idea/blaze/java/libraries/AddLibraryRuleDirectoryToProjectViewAction.java
+++ b/java/src/com/google/idea/blaze/java/libraries/AddLibraryRuleDirectoryToProjectViewAction.java
@@ -19,9 +19,9 @@
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.actions.BlazeAction;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
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.WorkspacePath;
import com.google.idea.blaze.base.projectview.ProjectViewEdit;
import com.google.idea.blaze.base.projectview.ProjectViewManager;
@@ -78,20 +78,20 @@
@Nullable
static WorkspacePath getDirectoryToAddForLibrary(Project project, Library library) {
- BlazeJarLibrary blazeLibrary =
- LibraryActionHelper.findLibraryFromIntellijLibrary(project, library);
- if (blazeLibrary == null) {
- return null;
- }
- Label originatingRule = blazeLibrary.originatingRule;
- if (originatingRule == null) {
- return null;
- }
BlazeProjectData blazeProjectData =
BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
if (blazeProjectData == null) {
return null;
}
+ BlazeJarLibrary blazeLibrary =
+ LibraryActionHelper.findLibraryFromIntellijLibrary(project, blazeProjectData, library);
+ if (blazeLibrary == null) {
+ return null;
+ }
+ RuleKey originatingRule = blazeLibrary.originatingRule;
+ if (originatingRule == null) {
+ return null;
+ }
RuleIdeInfo rule = blazeProjectData.ruleMap.get(originatingRule);
if (rule == null) {
return null;
diff --git a/java/src/com/google/idea/blaze/java/libraries/AttachSourceJarAction.java b/java/src/com/google/idea/blaze/java/libraries/AttachSourceJarAction.java
index ca216ac..d6daa4f 100644
--- a/java/src/com/google/idea/blaze/java/libraries/AttachSourceJarAction.java
+++ b/java/src/com/google/idea/blaze/java/libraries/AttachSourceJarAction.java
@@ -17,6 +17,8 @@
import com.google.idea.blaze.base.actions.BlazeAction;
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.java.sync.model.BlazeJarLibrary;
import com.google.idea.blaze.java.sync.projectstructure.LibraryEditor;
import com.intellij.CommonBundle;
@@ -35,10 +37,15 @@
public void actionPerformed(AnActionEvent e) {
Project project = e.getProject();
assert project != null;
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
+ if (blazeProjectData == null) {
+ return;
+ }
Library library = LibraryActionHelper.findLibraryForAction(e);
if (library != null) {
BlazeJarLibrary blazeLibrary =
- LibraryActionHelper.findLibraryFromIntellijLibrary(project, library);
+ LibraryActionHelper.findLibraryFromIntellijLibrary(project, blazeProjectData, library);
if (blazeLibrary == null) {
Messages.showErrorDialog(
project, "Could not find this library in the project.", CommonBundle.getErrorTitle());
@@ -58,7 +65,12 @@
() -> {
LibraryTable libraryTable = ProjectLibraryTable.getInstance(project);
LibraryTable.ModifiableModel libraryTableModel = libraryTable.getModifiableModel();
- LibraryEditor.updateLibrary(project, libraryTable, libraryTableModel, blazeLibrary);
+ LibraryEditor.updateLibrary(
+ project,
+ blazeProjectData.artifactLocationDecoder,
+ libraryTable,
+ libraryTableModel,
+ blazeLibrary);
libraryTableModel.commit();
});
}
@@ -72,16 +84,21 @@
boolean enabled = false;
Project project = e.getProject();
if (project != null) {
- Library library = LibraryActionHelper.findLibraryForAction(e);
- if (library != null) {
- visible = true;
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
+ if (blazeProjectData != null) {
+ Library library = LibraryActionHelper.findLibraryForAction(e);
+ if (library != null) {
+ visible = true;
- BlazeJarLibrary blazeLibrary =
- LibraryActionHelper.findLibraryFromIntellijLibrary(e.getProject(), library);
- if (blazeLibrary != null && blazeLibrary.libraryArtifact.sourceJar != null) {
- enabled = true;
- if (SourceJarManager.getInstance(project).hasSourceJarAttached(blazeLibrary.key)) {
- text = "Detach Source Jar";
+ BlazeJarLibrary blazeLibrary =
+ LibraryActionHelper.findLibraryFromIntellijLibrary(
+ e.getProject(), blazeProjectData, library);
+ if (blazeLibrary != null && blazeLibrary.libraryArtifact.sourceJar != null) {
+ enabled = true;
+ if (SourceJarManager.getInstance(project).hasSourceJarAttached(blazeLibrary.key)) {
+ text = "Detach Source Jar";
+ }
}
}
}
diff --git a/java/src/com/google/idea/blaze/java/libraries/BlazeAttachSourceProvider.java b/java/src/com/google/idea/blaze/java/libraries/BlazeAttachSourceProvider.java
index b70ba2f..04e0d8c 100644
--- a/java/src/com/google/idea/blaze/java/libraries/BlazeAttachSourceProvider.java
+++ b/java/src/com/google/idea/blaze/java/libraries/BlazeAttachSourceProvider.java
@@ -28,7 +28,6 @@
import com.google.idea.blaze.java.sync.projectstructure.LibraryEditor;
import com.intellij.codeInsight.AttachSourcesProvider;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
@@ -43,8 +42,6 @@
/** @author Sergey Evdokimov */
public class BlazeAttachSourceProvider implements AttachSourcesProvider {
- private static final Logger LOG = Logger.getInstance(BlazeAttachSourceProvider.class);
-
@NotNull
@Override
public Collection<AttachSourcesAction> getActions(
@@ -67,7 +64,7 @@
continue;
}
BlazeJarLibrary blazeLibrary =
- LibraryActionHelper.findLibraryFromIntellijLibrary(project, library);
+ LibraryActionHelper.findLibraryFromIntellijLibrary(project, blazeProjectData, library);
if (blazeLibrary == null) {
continue;
}
@@ -90,7 +87,7 @@
if (BlazeJavaUserSettings.getInstance().getAttachSourcesOnDemand()) {
UIUtil.invokeLaterIfNeeded(
() -> {
- attachSources(project, librariesToAttachSourceTo);
+ attachSources(project, blazeProjectData, librariesToAttachSourceTo);
});
return ImmutableList.of();
}
@@ -109,13 +106,16 @@
@Override
public ActionCallback perform(List<LibraryOrderEntry> orderEntriesContainingFile) {
- attachSources(project, librariesToAttachSourceTo);
+ attachSources(project, blazeProjectData, librariesToAttachSourceTo);
return ActionCallback.DONE;
}
});
}
- static void attachSources(Project project, Collection<BlazeLibrary> librariesToAttachSourceTo) {
+ static void attachSources(
+ Project project,
+ BlazeProjectData blazeProjectData,
+ Collection<BlazeLibrary> librariesToAttachSourceTo) {
ApplicationManager.getApplication()
.runWriteAction(
() -> {
@@ -128,7 +128,12 @@
}
SourceJarManager.getInstance(project)
.setHasSourceJarAttached(blazeLibrary.key, true);
- LibraryEditor.updateLibrary(project, libraryTable, libraryTableModel, blazeLibrary);
+ LibraryEditor.updateLibrary(
+ project,
+ blazeProjectData.artifactLocationDecoder,
+ libraryTable,
+ libraryTableModel,
+ blazeLibrary);
}
libraryTableModel.commit();
});
diff --git a/java/src/com/google/idea/blaze/java/libraries/DetachAllSourceJarsAction.java b/java/src/com/google/idea/blaze/java/libraries/DetachAllSourceJarsAction.java
new file mode 100644
index 0000000..f30518a
--- /dev/null
+++ b/java/src/com/google/idea/blaze/java/libraries/DetachAllSourceJarsAction.java
@@ -0,0 +1,77 @@
+/*
+ * 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.java.libraries;
+
+import com.google.common.collect.Lists;
+import com.google.idea.blaze.base.actions.BlazeAction;
+import com.google.idea.blaze.base.model.BlazeProjectData;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.java.sync.model.BlazeJarLibrary;
+import com.google.idea.blaze.java.sync.model.LibraryKey;
+import com.google.idea.blaze.java.sync.projectstructure.LibraryEditor;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import java.util.List;
+
+class DetachAllSourceJarsAction extends BlazeAction {
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ Project project = e.getProject();
+ assert project != null;
+
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
+ if (blazeProjectData == null) {
+ return;
+ }
+
+ List<Library> librariesToDetach = Lists.newArrayList();
+ SourceJarManager sourceJarManager = SourceJarManager.getInstance(project);
+ for (Library library : ProjectLibraryTable.getInstance(project).getLibraries()) {
+ LibraryKey libraryKey = LibraryKey.fromIntelliJLibrary(library);
+ if (sourceJarManager.hasSourceJarAttached(libraryKey)) {
+ sourceJarManager.setHasSourceJarAttached(libraryKey, false);
+ librariesToDetach.add(library);
+ }
+ }
+
+ ApplicationManager.getApplication()
+ .runWriteAction(
+ () -> {
+ LibraryTable libraryTable = ProjectLibraryTable.getInstance(project);
+ LibraryTable.ModifiableModel libraryTableModel = libraryTable.getModifiableModel();
+ for (Library library : librariesToDetach) {
+ BlazeJarLibrary blazeLibrary =
+ LibraryActionHelper.findLibraryFromIntellijLibrary(
+ e.getProject(), blazeProjectData, library);
+ if (blazeLibrary == null) {
+ continue;
+ }
+ LibraryEditor.updateLibrary(
+ project,
+ blazeProjectData.artifactLocationDecoder,
+ libraryTable,
+ libraryTableModel,
+ blazeLibrary);
+ }
+ libraryTableModel.commit();
+ });
+ }
+}
diff --git a/java/src/com/google/idea/blaze/java/libraries/ExcludeLibraryAction.java b/java/src/com/google/idea/blaze/java/libraries/ExcludeLibraryAction.java
index 8d2776e..53d4ae8 100644
--- a/java/src/com/google/idea/blaze/java/libraries/ExcludeLibraryAction.java
+++ b/java/src/com/google/idea/blaze/java/libraries/ExcludeLibraryAction.java
@@ -17,12 +17,14 @@
import com.google.idea.blaze.base.actions.BlazeAction;
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
+import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.projectview.ProjectViewEdit;
import com.google.idea.blaze.base.projectview.section.Glob;
import com.google.idea.blaze.base.projectview.section.ListSection;
import com.google.idea.blaze.base.settings.BlazeUserSettings;
import com.google.idea.blaze.base.sync.BlazeSyncManager;
import com.google.idea.blaze.base.sync.BlazeSyncParams;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.java.projectview.ExcludeLibrarySection;
import com.google.idea.blaze.java.sync.model.BlazeJarLibrary;
import com.intellij.CommonBundle;
@@ -38,45 +40,51 @@
public void actionPerformed(AnActionEvent e) {
Project project = e.getProject();
assert project != null;
- Library library = LibraryActionHelper.findLibraryForAction(e);
- if (library != null) {
- BlazeJarLibrary blazeLibrary =
- LibraryActionHelper.findLibraryFromIntellijLibrary(project, library);
- if (blazeLibrary == null) {
- Messages.showErrorDialog(
- project, "Could not find this library in the project.", CommonBundle.getErrorTitle());
- return;
- }
-
- final LibraryArtifact libraryArtifact = blazeLibrary.libraryArtifact;
- final String path = libraryArtifact.jarForIntellijLibrary().getRelativePath();
-
- ProjectViewEdit edit =
- ProjectViewEdit.editLocalProjectView(
- project,
- builder -> {
- ListSection<Glob> existingSection = builder.getLast(ExcludeLibrarySection.KEY);
- builder.replace(
- existingSection,
- ListSection.update(ExcludeLibrarySection.KEY, existingSection)
- .add(new Glob(path)));
- return true;
- });
- if (edit == null) {
- Messages.showErrorDialog(
- "Could not modify project view. Check for errors in your project view and try again",
- "Error");
- return;
- }
- edit.apply();
-
- BlazeSyncManager.getInstance(project)
- .requestProjectSync(
- new BlazeSyncParams.Builder("Sync", BlazeSyncParams.SyncMode.INCREMENTAL)
- .addProjectViewTargets(true)
- .addWorkingSet(BlazeUserSettings.getInstance().getExpandSyncToWorkingSet())
- .build());
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
+ if (blazeProjectData == null) {
+ return;
}
+ Library library = LibraryActionHelper.findLibraryForAction(e);
+ if (library == null) {
+ return;
+ }
+ BlazeJarLibrary blazeLibrary =
+ LibraryActionHelper.findLibraryFromIntellijLibrary(project, blazeProjectData, library);
+ if (blazeLibrary == null) {
+ Messages.showErrorDialog(
+ project, "Could not find this library in the project.", CommonBundle.getErrorTitle());
+ return;
+ }
+
+ final LibraryArtifact libraryArtifact = blazeLibrary.libraryArtifact;
+ final String path = libraryArtifact.jarForIntellijLibrary().getRelativePath();
+
+ ProjectViewEdit edit =
+ ProjectViewEdit.editLocalProjectView(
+ project,
+ builder -> {
+ ListSection<Glob> existingSection = builder.getLast(ExcludeLibrarySection.KEY);
+ builder.replace(
+ existingSection,
+ ListSection.update(ExcludeLibrarySection.KEY, existingSection)
+ .add(new Glob(path)));
+ return true;
+ });
+ if (edit == null) {
+ Messages.showErrorDialog(
+ "Could not modify project view. Check for errors in your project view and try again",
+ "Error");
+ return;
+ }
+ edit.apply();
+
+ BlazeSyncManager.getInstance(project)
+ .requestProjectSync(
+ new BlazeSyncParams.Builder("Sync", BlazeSyncParams.SyncMode.INCREMENTAL)
+ .addProjectViewTargets(true)
+ .addWorkingSet(BlazeUserSettings.getInstance().getExpandSyncToWorkingSet())
+ .build());
}
@Override
diff --git a/java/src/com/google/idea/blaze/java/libraries/JarCache.java b/java/src/com/google/idea/blaze/java/libraries/JarCache.java
index 33b5cad..b0a8ec1 100644
--- a/java/src/com/google/idea/blaze/java/libraries/JarCache.java
+++ b/java/src/com/google/idea/blaze/java/libraries/JarCache.java
@@ -34,6 +34,7 @@
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
import com.google.idea.blaze.base.sync.BlazeSyncParams;
import com.google.idea.blaze.base.sync.data.BlazeDataStorage;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.java.settings.BlazeJavaUserSettings;
import com.google.idea.blaze.java.sync.BlazeLibraryCollector;
import com.google.idea.blaze.java.sync.model.BlazeJarLibrary;
@@ -101,15 +102,17 @@
.map(library -> (BlazeJarLibrary) library)
.collect(Collectors.toList());
+ ArtifactLocationDecoder artifactLocationDecoder = projectData.artifactLocationDecoder;
BiMap<File, String> sourceFileToCacheKey = HashBiMap.create(jarLibraries.size());
for (BlazeJarLibrary library : jarLibraries) {
- File jarFile = library.libraryArtifact.jarForIntellijLibrary().getFile();
+ File jarFile =
+ artifactLocationDecoder.decode(library.libraryArtifact.jarForIntellijLibrary());
sourceFileToCacheKey.put(jarFile, cacheKeyForJar(jarFile));
boolean attachSourceJar =
attachAllSourceJars || sourceJarManager.hasSourceJarAttached(library.key);
if (attachSourceJar && library.libraryArtifact.sourceJar != null) {
- File srcJarFile = library.libraryArtifact.sourceJar.getFile();
+ File srcJarFile = artifactLocationDecoder.decode(library.libraryArtifact.sourceJar);
sourceFileToCacheKey.put(srcJarFile, cacheKeyForSourceJar(srcJarFile));
}
}
@@ -262,8 +265,8 @@
}
/** Gets the cached file for a jar. If it doesn't exist, we return the file from the library. */
- public File getCachedJar(BlazeJarLibrary library) {
- File file = library.libraryArtifact.jarForIntellijLibrary().getFile();
+ public File getCachedJar(ArtifactLocationDecoder decoder, BlazeJarLibrary library) {
+ File file = decoder.decode(library.libraryArtifact.jarForIntellijLibrary());
if (!enabled || sourceFileToCacheKey == null) {
return file;
}
@@ -276,11 +279,11 @@
/** Gets the cached file for a source jar. */
@Nullable
- public File getCachedSourceJar(BlazeJarLibrary library) {
+ public File getCachedSourceJar(ArtifactLocationDecoder decoder, BlazeJarLibrary library) {
if (library.libraryArtifact.sourceJar == null) {
return null;
}
- File file = library.libraryArtifact.sourceJar.getFile();
+ File file = decoder.decode(library.libraryArtifact.sourceJar);
if (!enabled || sourceFileToCacheKey == null) {
return file;
}
diff --git a/java/src/com/google/idea/blaze/java/libraries/LibraryActionHelper.java b/java/src/com/google/idea/blaze/java/libraries/LibraryActionHelper.java
index 3b3132c..7e7db55 100644
--- a/java/src/com/google/idea/blaze/java/libraries/LibraryActionHelper.java
+++ b/java/src/com/google/idea/blaze/java/libraries/LibraryActionHelper.java
@@ -16,7 +16,6 @@
package com.google.idea.blaze.java.libraries;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.java.sync.model.BlazeJarLibrary;
import com.google.idea.blaze.java.sync.model.BlazeJavaSyncData;
import com.google.idea.blaze.java.sync.model.BlazeLibrary;
@@ -37,14 +36,10 @@
class LibraryActionHelper {
- static BlazeJarLibrary findLibraryFromIntellijLibrary(Project project, Library library) {
+ static BlazeJarLibrary findLibraryFromIntellijLibrary(
+ Project project, BlazeProjectData blazeProjectData, Library library) {
LibraryKey libraryKey = LibraryKey.fromIntelliJLibrary(library);
- BlazeProjectData projectData =
- BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
- if (projectData == null) {
- return null;
- }
- BlazeJavaSyncData syncData = projectData.syncState.get(BlazeJavaSyncData.class);
+ BlazeJavaSyncData syncData = blazeProjectData.syncState.get(BlazeJavaSyncData.class);
if (syncData == null) {
Messages.showErrorDialog(project, "Project isn't synced. Please resync project.", "Error");
return null;
diff --git a/java/src/com/google/idea/blaze/java/run/BlazeJavaDebuggerRunner.java b/java/src/com/google/idea/blaze/java/run/BlazeJavaDebuggerRunner.java
index 55f9900..001f26e 100644
--- a/java/src/com/google/idea/blaze/java/run/BlazeJavaDebuggerRunner.java
+++ b/java/src/com/google/idea/blaze/java/run/BlazeJavaDebuggerRunner.java
@@ -15,7 +15,7 @@
*/
package com.google.idea.blaze.java.run;
-import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.intellij.debugger.impl.GenericDebuggerRunner;
import com.intellij.execution.ExecutionException;
@@ -43,8 +43,8 @@
if (executorId.equals(DefaultDebugExecutor.EXECUTOR_ID)
&& profile instanceof BlazeCommandRunConfiguration) {
BlazeCommandRunConfiguration configuration = (BlazeCommandRunConfiguration) profile;
- RuleIdeInfo rule = configuration.getRuleForTarget();
- return rule != null && BlazeJavaRunConfigurationHandlerProvider.supportsKind(rule.kind);
+ Kind kind = configuration.getKindForTarget();
+ return kind != null && BlazeJavaRunConfigurationHandlerProvider.supportsKind(kind);
}
return false;
}
diff --git a/java/src/com/google/idea/blaze/java/run/BlazeJavaRuleConfigurationFactory.java b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationFactory.java
similarity index 61%
rename from java/src/com/google/idea/blaze/java/run/BlazeJavaRuleConfigurationFactory.java
rename to java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationFactory.java
index 2ed1ca8..eb2c0d2 100644
--- a/java/src/com/google/idea/blaze/java/run/BlazeJavaRuleConfigurationFactory.java
+++ b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationFactory.java
@@ -17,21 +17,24 @@
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+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.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.BlazeRuleConfigurationFactory;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
-import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
+import com.google.idea.blaze.base.run.BlazeRunConfigurationFactory;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.openapi.project.Project;
/** Creates run configurations for java_binary. */
-public class BlazeJavaRuleConfigurationFactory extends BlazeRuleConfigurationFactory {
+public class BlazeJavaRunConfigurationFactory extends BlazeRunConfigurationFactory {
@Override
- public boolean handlesRule(
- WorkspaceLanguageSettings workspaceLanguageSettings, RuleIdeInfo rule) {
- return rule.kind == Kind.JAVA_BINARY;
+ public boolean handlesTarget(Project project, BlazeProjectData blazeProjectData, Label target) {
+ RuleIdeInfo rule = blazeProjectData.ruleMap.get(RuleKey.forPlainTarget(target));
+ return rule != null && rule.kind == Kind.JAVA_BINARY;
}
@Override
@@ -40,14 +43,15 @@
}
@Override
- public void setupConfiguration(RunConfiguration configuration, RuleIdeInfo rule) {
+ public void setupConfiguration(RunConfiguration configuration, Label target) {
final BlazeCommandRunConfiguration blazeConfig = (BlazeCommandRunConfiguration) configuration;
- blazeConfig.setTarget(rule.label);
+ blazeConfig.setTarget(target);
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) blazeConfig.getHandler();
- handler.setCommand(BlazeCommandName.RUN);
-
+ BlazeCommandRunConfigurationCommonState state =
+ blazeConfig.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (state != null) {
+ state.setCommand(BlazeCommandName.RUN);
+ }
blazeConfig.setGeneratedName();
}
}
diff --git a/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationHandler.java b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationHandler.java
new file mode 100644
index 0000000..fd26ffd
--- /dev/null
+++ b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationHandler.java
@@ -0,0 +1,100 @@
+/*
+ * 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.java.run;
+
+import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
+import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
+import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationRunner;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
+import com.google.idea.blaze.base.settings.Blaze;
+import com.intellij.execution.Executor;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.execution.configurations.RunProfileState;
+import com.intellij.execution.configurations.RuntimeConfigurationException;
+import com.intellij.execution.executors.DefaultDebugExecutor;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import javax.annotation.Nullable;
+import javax.swing.Icon;
+
+/** Java-specific handler for {@link BlazeCommandRunConfiguration}s. */
+public final class BlazeJavaRunConfigurationHandler implements BlazeCommandRunConfigurationHandler {
+
+ private final String buildSystemName;
+ private final BlazeCommandRunConfigurationCommonState state;
+
+ public BlazeJavaRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
+ this.buildSystemName = Blaze.buildSystemName(configuration.getProject());
+ this.state = new BlazeCommandRunConfigurationCommonState(buildSystemName);
+ }
+
+ @Override
+ public BlazeCommandRunConfigurationCommonState getState() {
+ return state;
+ }
+
+ @Override
+ public BlazeCommandRunConfigurationRunner createRunner(
+ Executor executor, ExecutionEnvironment environment) {
+ return new BlazeJavaRunConfigurationRunner();
+ }
+
+ @Override
+ public void checkConfiguration() throws RuntimeConfigurationException {
+ state.validate(buildSystemName);
+ }
+
+ @Override
+ @Nullable
+ public String suggestedName(BlazeCommandRunConfiguration configuration) {
+ if (configuration.getTarget() == null) {
+ return null;
+ }
+ return new BlazeConfigurationNameBuilder(configuration).build();
+ }
+
+ @Override
+ @Nullable
+ public String getCommandName() {
+ BlazeCommandName command = state.getCommand();
+ return command != null ? command.toString() : null;
+ }
+
+ @Override
+ public String getHandlerName() {
+ return "Java Handler";
+ }
+
+ @Override
+ @Nullable
+ public Icon getExecutorIcon(RunConfiguration configuration, Executor executor) {
+ return null;
+ }
+
+ private static class BlazeJavaRunConfigurationRunner
+ implements BlazeCommandRunConfigurationRunner {
+ @Override
+ public RunProfileState getRunProfileState(Executor executor, ExecutionEnvironment environment) {
+ return new BlazeJavaRunProfileState(environment, executor instanceof DefaultDebugExecutor);
+ }
+
+ @Override
+ public boolean executeBeforeRunTask(ExecutionEnvironment environment) {
+ return true;
+ }
+ }
+}
diff --git a/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationHandlerProvider.java b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationHandlerProvider.java
index 966fe91..ca6a022 100644
--- a/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationHandlerProvider.java
+++ b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunConfigurationHandlerProvider.java
@@ -18,15 +18,10 @@
import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandler;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerProvider;
-import com.intellij.execution.Executor;
-import com.intellij.execution.configurations.RunProfileState;
-import com.intellij.execution.executors.DefaultDebugExecutor;
-import com.intellij.execution.runners.ExecutionEnvironment;
-/** Java-specific handler for {@link BlazeCommandRunConfiguration}s. */
+/** Java-specific handler provider for {@link BlazeCommandRunConfiguration}s. */
public class BlazeJavaRunConfigurationHandlerProvider
implements BlazeCommandRunConfigurationHandlerProvider {
@@ -52,31 +47,4 @@
return "BlazeJavaRunConfigurationHandlerProvider";
}
- private static class BlazeJavaRunConfigurationHandler
- extends BlazeCommandGenericRunConfigurationHandler {
-
- BlazeJavaRunConfigurationHandler(BlazeCommandRunConfiguration configuration) {
- super(configuration);
- }
-
- private BlazeJavaRunConfigurationHandler(
- BlazeJavaRunConfigurationHandler other, BlazeCommandRunConfiguration configuration) {
- super(other, configuration);
- }
-
- @Override
- public BlazeJavaRunConfigurationHandler cloneFor(BlazeCommandRunConfiguration configuration) {
- return new BlazeJavaRunConfigurationHandler(this, configuration);
- }
-
- @Override
- public RunProfileState getState(Executor executor, ExecutionEnvironment environment) {
- return new BlazeJavaRunProfileState(environment, executor instanceof DefaultDebugExecutor);
- }
-
- @Override
- public String getHandlerName() {
- return "Java Handler";
- }
- }
}
diff --git a/java/src/com/google/idea/blaze/java/run/BlazeJavaRunProfileState.java b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunProfileState.java
index 935a1e0..a712e65 100644
--- a/java/src/com/google/idea/blaze/java/run/BlazeJavaRunProfileState.java
+++ b/java/src/com/google/idea/blaze/java/run/BlazeJavaRunProfileState.java
@@ -21,7 +21,6 @@
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.ideinfo.RuleIdeInfo;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.metrics.Action;
import com.google.idea.blaze.base.model.primitives.Kind;
@@ -29,9 +28,9 @@
import com.google.idea.blaze.base.projectview.ProjectViewManager;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
import com.google.idea.blaze.base.run.processhandler.LineProcessingProcessAdapter;
import com.google.idea.blaze.base.run.processhandler.ScopedBlazeProcessHandler;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.scopes.IdeaLogScope;
import com.google.idea.blaze.base.scope.scopes.IssuesScope;
@@ -125,26 +124,22 @@
ProjectViewSet projectViewSet,
boolean debug) {
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- assert handler != null;
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ assert handlerState != null;
- BlazeCommandName blazeCommand = handler.getCommand();
+ BlazeCommandName blazeCommand = handlerState.getCommand();
assert blazeCommand != null;
BlazeCommand.Builder command =
BlazeCommand.builder(Blaze.getBuildSystem(project), blazeCommand)
- .setBlazeBinary(handler.getBlazeBinary())
+ .setBlazeBinary(handlerState.getBlazeBinary())
.addTargets(configuration.getTarget())
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
- .addBlazeFlags(handler.getAllBlazeFlags());
+ .addBlazeFlags(handlerState.getBlazeFlags());
if (debug) {
- boolean isJavaBinary = false;
- RuleIdeInfo rule = configuration.getRuleForTarget();
- if (rule != null && (rule.kind == Kind.JAVA_BINARY)) {
- isJavaBinary = true;
- }
-
+ Kind kind = configuration.getKindForTarget();
+ boolean isJavaBinary = kind == Kind.JAVA_BINARY;
if (isJavaBinary) {
command.addExeFlags(BlazeFlags.JAVA_BINARY_DEBUG);
} else {
@@ -152,7 +147,7 @@
}
}
- command.addExeFlags(handler.getAllExeFlags());
+ command.addExeFlags(handlerState.getExeFlags());
return command.build();
}
}
diff --git a/java/src/com/google/idea/blaze/java/run/BlazeJavaTestRuleConfigurationFactory.java b/java/src/com/google/idea/blaze/java/run/BlazeJavaTestRunConfigurationFactory.java
similarity index 61%
rename from java/src/com/google/idea/blaze/java/run/BlazeJavaTestRuleConfigurationFactory.java
rename to java/src/com/google/idea/blaze/java/run/BlazeJavaTestRunConfigurationFactory.java
index 42c6256..0722e86 100644
--- a/java/src/com/google/idea/blaze/java/run/BlazeJavaTestRuleConfigurationFactory.java
+++ b/java/src/com/google/idea/blaze/java/run/BlazeJavaTestRunConfigurationFactory.java
@@ -17,21 +17,24 @@
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+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.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.BlazeRuleConfigurationFactory;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
-import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
+import com.google.idea.blaze.base.run.BlazeRunConfigurationFactory;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.openapi.project.Project;
/** Creates run configurations for java_test and android_robolectric_test. */
-public class BlazeJavaTestRuleConfigurationFactory extends BlazeRuleConfigurationFactory {
+public class BlazeJavaTestRunConfigurationFactory extends BlazeRunConfigurationFactory {
@Override
- public boolean handlesRule(
- WorkspaceLanguageSettings workspaceLanguageSettings, RuleIdeInfo rule) {
- return rule.kindIsOneOf(Kind.JAVA_TEST, Kind.ANDROID_ROBOLECTRIC_TEST);
+ public boolean handlesTarget(Project project, BlazeProjectData blazeProjectData, Label target) {
+ RuleIdeInfo rule = blazeProjectData.ruleMap.get(RuleKey.forPlainTarget(target));
+ return rule != null && rule.kindIsOneOf(Kind.JAVA_TEST, Kind.ANDROID_ROBOLECTRIC_TEST);
}
@Override
@@ -40,14 +43,15 @@
}
@Override
- public void setupConfiguration(RunConfiguration configuration, RuleIdeInfo rule) {
+ public void setupConfiguration(RunConfiguration configuration, Label target) {
final BlazeCommandRunConfiguration blazeConfig = (BlazeCommandRunConfiguration) configuration;
- blazeConfig.setTarget(rule.label);
+ blazeConfig.setTarget(target);
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) blazeConfig.getHandler();
- handler.setCommand(BlazeCommandName.TEST);
-
+ BlazeCommandRunConfigurationCommonState state =
+ blazeConfig.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (state != null) {
+ state.setCommand(BlazeCommandName.TEST);
+ }
blazeConfig.setGeneratedName();
}
}
diff --git a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassRunConfigurationProducer.java b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassRunConfigurationProducer.java
index 72c35f6..43ba6d0 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassRunConfigurationProducer.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaMainClassRunConfigurationProducer.java
@@ -18,15 +18,15 @@
import com.google.common.collect.ImmutableCollection;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.primitives.Kind;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.rulemaps.SourceToRuleMap;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
import com.google.idea.blaze.base.run.producers.BlazeRunConfigurationProducer;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.blaze.java.run.RunUtil;
import com.intellij.execution.JavaExecutionUtil;
@@ -40,7 +40,9 @@
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiMethodUtil;
import java.io.File;
+import java.util.List;
import java.util.Objects;
+import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable;
/** Creates run configurations for Java main classes sourced by java_binary targets. */
@@ -74,12 +76,12 @@
return false;
}
configuration.setTarget(label);
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
return false;
}
- handler.setCommand(BlazeCommandName.RUN);
+ handlerState.setCommand(BlazeCommandName.RUN);
configuration.setGeneratedName();
return true;
}
@@ -87,12 +89,12 @@
@Override
protected boolean doIsConfigFromContext(
BlazeCommandRunConfiguration configuration, ConfigurationContext context) {
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
return false;
}
- if (!Objects.equals(handler.getCommand(), BlazeCommandName.RUN)) {
+ if (!Objects.equals(handlerState.getCommand(), BlazeCommandName.RUN)) {
return false;
}
PsiClass mainClass = getMainClass(context);
@@ -126,20 +128,25 @@
@Nullable
private static Label getRuleLabel(Project project, PsiClass mainClass) {
File mainClassFile = RunUtil.getFileForClass(mainClass);
- ImmutableCollection<Label> labels =
- SourceToRuleMap.getInstance(project).getTargetsForSourceFile(mainClassFile);
+ ImmutableCollection<RuleKey> ruleKeys =
+ SourceToRuleMap.getInstance(project).getRulesForSourceFile(mainClassFile);
BlazeProjectData blazeProjectData =
BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
if (blazeProjectData == null) {
return null;
}
- RuleMap ruleMap = blazeProjectData.ruleMap;
- for (Label label : labels) {
- RuleIdeInfo rule = ruleMap.get(label);
+ List<RuleIdeInfo> rules =
+ ruleKeys
+ .stream()
+ .map(blazeProjectData.ruleMap::get)
+ .filter(Objects::nonNull)
+ .filter(RuleIdeInfo::isPlainTarget)
+ .collect(Collectors.toList());
+ for (RuleIdeInfo rule : rules) {
if (rule.kind == Kind.JAVA_BINARY) {
// Best-effort guess: the main_class attribute isn't exposed, but assume
// mainClass is the main_class because it is sourced by the java_binary.
- return label;
+ return rule.label;
}
}
return null;
diff --git a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducer.java b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducer.java
index c9c4c3e..cd1764c 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducer.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestClassConfigurationProducer.java
@@ -23,8 +23,8 @@
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
import com.google.idea.blaze.base.run.producers.BlazeRunConfigurationProducer;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.java.run.RunUtil;
import com.intellij.execution.JavaExecutionUtil;
import com.intellij.execution.Location;
@@ -76,12 +76,12 @@
}
configuration.setTarget(rule.label);
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
return false;
}
- handler.setCommand(BlazeCommandName.TEST);
+ handlerState.setCommand(BlazeCommandName.TEST);
ImmutableList.Builder<String> flags = ImmutableList.builder();
@@ -91,9 +91,9 @@
}
flags.add(BlazeFlags.TEST_OUTPUT_STREAMED);
- flags.addAll(handler.getAllBlazeFlags());
+ flags.addAll(handlerState.getBlazeFlags());
- handler.setBlazeFlags(flags.build());
+ handlerState.setBlazeFlags(flags.build());
BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration);
nameBuilder.setTargetString(testClass.getName());
@@ -132,15 +132,15 @@
private boolean checkIfAttributesAreTheSame(
@NotNull BlazeCommandRunConfiguration configuration, @NotNull PsiClass testClass) {
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
return false;
}
- if (!Objects.equals(handler.getCommand(), BlazeCommandName.TEST)) {
+ if (!Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)) {
return false;
}
- List<String> flags = handler.getAllBlazeFlags();
+ List<String> flags = handlerState.getBlazeFlags();
return flags.contains(BlazeFlags.testFilterFlagForClass(testClass.getQualifiedName()));
}
diff --git a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducer.java b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducer.java
index 4b67696..d10be31 100644
--- a/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducer.java
+++ b/java/src/com/google/idea/blaze/java/run/producers/BlazeJavaTestMethodConfigurationProducer.java
@@ -23,8 +23,8 @@
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
import com.google.idea.blaze.base.run.BlazeConfigurationNameBuilder;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
import com.google.idea.blaze.base.run.producers.BlazeRunConfigurationProducer;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.java.run.RunUtil;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.junit.JUnitUtil;
@@ -88,19 +88,19 @@
}
configuration.setTarget(rule.label);
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
return false;
}
- handler.setCommand(BlazeCommandName.TEST);
+ handlerState.setCommand(BlazeCommandName.TEST);
ImmutableList.Builder<String> flags = ImmutableList.builder();
flags.add(methodInfo.testFilterFlag);
flags.add(BlazeFlags.TEST_OUTPUT_STREAMED);
- flags.addAll(handler.getAllBlazeFlags());
+ flags.addAll(handlerState.getBlazeFlags());
- handler.setBlazeFlags(flags.build());
+ handlerState.setBlazeFlags(flags.build());
BlazeConfigurationNameBuilder nameBuilder = new BlazeConfigurationNameBuilder(configuration);
nameBuilder.setTargetString(
@@ -115,12 +115,12 @@
@Override
protected boolean doIsConfigFromContext(
@NotNull BlazeCommandRunConfiguration configuration, @NotNull ConfigurationContext context) {
- BlazeCommandGenericRunConfigurationHandler handler =
- configuration.getHandlerIfType(BlazeCommandGenericRunConfigurationHandler.class);
- if (handler == null) {
+ BlazeCommandRunConfigurationCommonState handlerState =
+ configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
+ if (handlerState == null) {
return false;
}
- if (!Objects.equals(handler.getCommand(), BlazeCommandName.TEST)) {
+ if (!Objects.equals(handlerState.getCommand(), BlazeCommandName.TEST)) {
return false;
}
@@ -129,7 +129,7 @@
return false;
}
- List<String> flags = handler.getAllBlazeFlags();
+ List<String> flags = handlerState.getBlazeFlags();
return flags.contains(methodInfo.testFilterFlag);
}
diff --git a/java/src/com/google/idea/blaze/java/sync/BlazeJavaSyncPlugin.java b/java/src/com/google/idea/blaze/java/sync/BlazeJavaSyncPlugin.java
index 9d6eb17..257dcab 100644
--- a/java/src/com/google/idea/blaze/java/sync/BlazeJavaSyncPlugin.java
+++ b/java/src/com/google/idea/blaze/java/sync/BlazeJavaSyncPlugin.java
@@ -19,8 +19,8 @@
import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
import com.google.idea.blaze.base.model.SyncState;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
@@ -43,6 +43,7 @@
import com.google.idea.blaze.java.projectview.ExcludedLibrarySection;
import com.google.idea.blaze.java.projectview.JavaLanguageLevelSection;
import com.google.idea.blaze.java.sync.importer.BlazeJavaWorkspaceImporter;
+import com.google.idea.blaze.java.sync.importer.JavaSourceFilter;
import com.google.idea.blaze.java.sync.jdeps.JdepsFileReader;
import com.google.idea.blaze.java.sync.jdeps.JdepsMap;
import com.google.idea.blaze.java.sync.model.BlazeJarLibrary;
@@ -54,7 +55,6 @@
import com.google.idea.blaze.java.sync.projectstructure.SourceFolderEditor;
import com.google.idea.blaze.java.sync.workingset.JavaWorkingSet;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
@@ -73,7 +73,6 @@
/** Sync support for Java. */
public class BlazeJavaSyncPlugin extends BlazeSyncPlugin.Adapter {
- private static final Logger LOG = Logger.getInstance(BlazeJavaSyncPlugin.class);
private final JdepsFileReader jdepsFileReader = new JdepsFileReader();
@Nullable
@@ -109,6 +108,7 @@
BlazeRoots blazeRoots,
@Nullable WorkingSet workingSet,
WorkspacePathResolver workspacePathResolver,
+ ArtifactLocationDecoder artifactLocationDecoder,
RuleMap ruleMap,
SyncState.Builder syncStateBuilder,
@Nullable SyncState previousSyncState) {
@@ -117,9 +117,17 @@
javaWorkingSet = new JavaWorkingSet(workspaceRoot, workingSet);
}
+ JavaSourceFilter sourceFilter =
+ new JavaSourceFilter(project, workspaceRoot, projectViewSet, ruleMap);
+
JdepsMap jdepsMap =
jdepsFileReader.loadJdepsFiles(
- project, context, ruleMap, syncStateBuilder, previousSyncState);
+ project,
+ context,
+ artifactLocationDecoder,
+ sourceFilter.getSourceRules(),
+ syncStateBuilder,
+ previousSyncState);
if (context.isCancelled()) {
return;
}
@@ -127,14 +135,14 @@
BlazeJavaWorkspaceImporter blazeJavaWorkspaceImporter =
new BlazeJavaWorkspaceImporter(
project,
- context,
workspaceRoot,
projectViewSet,
workspaceLanguageSettings,
ruleMap,
+ sourceFilter,
jdepsMap,
javaWorkingSet,
- new ArtifactLocationDecoder(blazeRoots, workspacePathResolver));
+ artifactLocationDecoder);
BlazeJavaImportResult importResult =
Scope.push(
context,
diff --git a/java/src/com/google/idea/blaze/java/sync/DuplicateSourceDetector.java b/java/src/com/google/idea/blaze/java/sync/DuplicateSourceDetector.java
index 9357346..13d5fbf 100644
--- a/java/src/com/google/idea/blaze/java/sync/DuplicateSourceDetector.java
+++ b/java/src/com/google/idea/blaze/java/sync/DuplicateSourceDetector.java
@@ -20,7 +20,7 @@
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
-import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.PerformanceWarning;
import java.util.Collection;
@@ -30,30 +30,30 @@
/** Detects and reports duplicate sources */
public class DuplicateSourceDetector {
- Multimap<ArtifactLocation, Label> artifacts = ArrayListMultimap.create();
+ Multimap<ArtifactLocation, RuleKey> artifacts = ArrayListMultimap.create();
- public void add(Label label, ArtifactLocation artifactLocation) {
- artifacts.put(artifactLocation, label);
+ public void add(RuleKey ruleKey, ArtifactLocation artifactLocation) {
+ artifacts.put(artifactLocation, ruleKey);
}
static class Duplicate {
final ArtifactLocation artifactLocation;
- final Collection<Label> labels;
+ final Collection<RuleKey> rules;
- public Duplicate(ArtifactLocation artifactLocation, Collection<Label> labels) {
+ public Duplicate(ArtifactLocation artifactLocation, Collection<RuleKey> rules) {
this.artifactLocation = artifactLocation;
- this.labels = labels;
+ this.rules = rules;
}
}
public void reportDuplicates(BlazeContext context) {
List<Duplicate> duplicates = Lists.newArrayList();
for (ArtifactLocation key : artifacts.keySet()) {
- Collection<Label> labels = artifacts.get(key);
+ Collection<RuleKey> labels = artifacts.get(key);
if (labels.size() > 1) {
// Workaround for aspect bug. Can be removed after the next blaze release, as of May 27 2016
- Set<Label> labelSet = Sets.newHashSet(labels);
+ Set<RuleKey> labelSet = Sets.newHashSet(labels);
if (labelSet.size() > 1) {
duplicates.add(new Duplicate(key, labelSet));
}
@@ -76,8 +76,8 @@
ArtifactLocation artifactLocation = duplicate.artifactLocation;
context.output(new PerformanceWarning(" Source: " + artifactLocation.getRelativePath()));
context.output(new PerformanceWarning(" Consumed by rules:"));
- for (Label label : duplicate.labels) {
- context.output(new PerformanceWarning(" " + label));
+ for (RuleKey ruleKey : duplicate.rules) {
+ context.output(new PerformanceWarning(" " + ruleKey.label));
}
context.output(new PerformanceWarning("")); // Newline
}
diff --git a/java/src/com/google/idea/blaze/java/sync/JavaPrefetchFileSource.java b/java/src/com/google/idea/blaze/java/sync/JavaPrefetchFileSource.java
index b77741a..21b3cd2 100644
--- a/java/src/com/google/idea/blaze/java/sync/JavaPrefetchFileSource.java
+++ b/java/src/com/google/idea/blaze/java/sync/JavaPrefetchFileSource.java
@@ -18,6 +18,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.prefetch.PrefetchFileSource;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.java.libraries.JarCache;
import com.google.idea.blaze.java.libraries.SourceJarManager;
import com.google.idea.blaze.java.settings.BlazeJavaUserSettings;
@@ -46,17 +47,18 @@
BlazeJavaUserSettings.getInstance().getAttachSourcesByDefault();
SourceJarManager sourceJarManager = SourceJarManager.getInstance(project);
Collection<BlazeLibrary> libraries = BlazeLibraryCollector.getLibraries(blazeProjectData);
+ ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
for (BlazeLibrary library : libraries) {
if (!(library instanceof BlazeJarLibrary)) {
continue;
}
BlazeJarLibrary jarLibrary = (BlazeJarLibrary) library;
- files.add(jarLibrary.libraryArtifact.jarForIntellijLibrary().getFile());
+ files.add(artifactLocationDecoder.decode(jarLibrary.libraryArtifact.jarForIntellijLibrary()));
boolean attachSourceJar =
attachSourcesByDefault || sourceJarManager.hasSourceJarAttached(jarLibrary.key);
if (attachSourceJar && jarLibrary.libraryArtifact.sourceJar != null) {
- files.add(jarLibrary.libraryArtifact.sourceJar.getFile());
+ files.add(artifactLocationDecoder.decode(jarLibrary.libraryArtifact.sourceJar));
}
}
}
diff --git a/java/src/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporter.java b/java/src/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporter.java
index 61d7155..4ef5bf8 100644
--- a/java/src/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporter.java
+++ b/java/src/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporter.java
@@ -29,8 +29,8 @@
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
import com.google.idea.blaze.base.ideinfo.ProtoLibraryLegacyInfo;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.RuleMap;
-import com.google.idea.blaze.base.model.primitives.Kind;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
@@ -38,7 +38,6 @@
import com.google.idea.blaze.base.scope.output.PrintOutput;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.sync.projectview.ImportRoots;
-import com.google.idea.blaze.base.sync.projectview.ProjectViewRuleImportFilter;
import com.google.idea.blaze.base.sync.projectview.SourceTestConfig;
import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
@@ -52,10 +51,7 @@
import com.google.idea.blaze.java.sync.source.SourceArtifact;
import com.google.idea.blaze.java.sync.source.SourceDirectoryCalculator;
import com.google.idea.blaze.java.sync.workingset.JavaWorkingSet;
-import com.google.idea.common.experiments.BoolExperiment;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
-import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -65,13 +61,7 @@
/** Builds a BlazeWorkspace. */
public final class BlazeJavaWorkspaceImporter {
- private static final Logger LOG = Logger.getInstance(BlazeJavaWorkspaceImporter.class);
-
- private static final BoolExperiment NO_EMPTY_SOURCE_RULES =
- new BoolExperiment("no.empty.source.rules", true);
-
private final Project project;
- private final BlazeContext context;
private final WorkspaceRoot workspaceRoot;
private final ImportRoots importRoots;
private final RuleMap ruleMap;
@@ -79,87 +69,39 @@
private final JdepsMap jdepsMap;
@Nullable private final JavaWorkingSet workingSet;
private final ArtifactLocationDecoder artifactLocationDecoder;
- private final ProjectViewRuleImportFilter importFilter;
private final DuplicateSourceDetector duplicateSourceDetector = new DuplicateSourceDetector();
private final Collection<BlazeJavaSyncAugmenter> augmenters;
+ private final JavaSourceFilter sourceFilter;
public BlazeJavaWorkspaceImporter(
Project project,
- BlazeContext context,
WorkspaceRoot workspaceRoot,
ProjectViewSet projectViewSet,
WorkspaceLanguageSettings workspaceLanguageSettings,
RuleMap ruleMap,
+ JavaSourceFilter sourceFilter,
JdepsMap jdepsMap,
@Nullable JavaWorkingSet workingSet,
ArtifactLocationDecoder artifactLocationDecoder) {
this.project = project;
- this.context = context;
this.workspaceRoot = workspaceRoot;
this.importRoots =
ImportRoots.builder(workspaceRoot, Blaze.getBuildSystem(project))
.add(projectViewSet)
.build();
this.ruleMap = ruleMap;
+ this.sourceFilter = sourceFilter;
this.jdepsMap = jdepsMap;
this.workingSet = workingSet;
this.artifactLocationDecoder = artifactLocationDecoder;
- this.importFilter = new ProjectViewRuleImportFilter(project, workspaceRoot, projectViewSet);
this.sourceTestConfig = new SourceTestConfig(projectViewSet);
this.augmenters = BlazeJavaSyncAugmenter.getActiveSyncAgumenters(workspaceLanguageSettings);
}
public BlazeJavaImportResult importWorkspace(BlazeContext context) {
- List<RuleIdeInfo> includedRules =
- ruleMap
- .rules()
- .stream()
- .filter(rule -> !importFilter.excludeTarget(rule))
- .collect(Collectors.toList());
-
- List<RuleIdeInfo> javaRules =
- includedRules
- .stream()
- .filter(rule -> rule.javaRuleIdeInfo != null)
- .collect(Collectors.toList());
-
- Map<Label, Collection<ArtifactLocation>> ruleToJavaSources = Maps.newHashMap();
- for (RuleIdeInfo rule : javaRules) {
- List<ArtifactLocation> javaSources =
- rule.sources
- .stream()
- .filter(source -> source.getRelativePath().endsWith(".java"))
- .collect(Collectors.toList());
- ruleToJavaSources.put(rule.label, javaSources);
- }
-
- boolean noEmptySourceRules = NO_EMPTY_SOURCE_RULES.getValue();
- List<RuleIdeInfo> sourceRules = Lists.newArrayList();
- List<RuleIdeInfo> libraryRules = Lists.newArrayList();
- for (RuleIdeInfo rule : javaRules) {
- boolean importAsSource =
- importFilter.isSourceRule(rule)
- && canImportAsSource(rule)
- && (noEmptySourceRules
- ? anyNonGeneratedSources(ruleToJavaSources.get(rule.label))
- : !allSourcesGenerated(ruleToJavaSources.get(rule.label)));
-
- if (importAsSource) {
- sourceRules.add(rule);
- } else {
- libraryRules.add(rule);
- }
- }
-
- List<RuleIdeInfo> protoLibraries =
- includedRules
- .stream()
- .filter(rule -> rule.kind == Kind.PROTO_LIBRARY)
- .collect(Collectors.toList());
-
WorkspaceBuilder workspaceBuilder = new WorkspaceBuilder();
- for (RuleIdeInfo rule : sourceRules) {
- addRuleAsSource(workspaceBuilder, rule, ruleToJavaSources.get(rule.label));
+ for (RuleIdeInfo rule : sourceFilter.sourceRules) {
+ addRuleAsSource(workspaceBuilder, rule, sourceFilter.ruleToJavaSources.get(rule.key));
}
SourceDirectoryCalculator sourceDirectoryCalculator = new SourceDirectoryCalculator();
@@ -181,7 +123,8 @@
context.output(PrintOutput.log("Java content entry count: " + totalContentEntryCount));
ImmutableMap<LibraryKey, BlazeJarLibrary> libraries =
- buildLibraries(workspaceBuilder, ruleMap, libraryRules, protoLibraries);
+ buildLibraries(
+ workspaceBuilder, ruleMap, sourceFilter.libraryRules, sourceFilter.protoLibraries);
duplicateSourceDetector.reportDuplicates(context);
@@ -196,31 +139,19 @@
sourceVersion);
}
- private boolean canImportAsSource(RuleIdeInfo rule) {
- return !rule.kindIsOneOf(Kind.JAVA_WRAP_CC, Kind.JAVA_IMPORT);
- }
-
- private boolean allSourcesGenerated(Collection<ArtifactLocation> sources) {
- return !sources.isEmpty() && sources.stream().allMatch(ArtifactLocation::isGenerated);
- }
-
- private boolean anyNonGeneratedSources(Collection<ArtifactLocation> sources) {
- return sources.stream().anyMatch(ArtifactLocation::isSource);
- }
-
private ImmutableMap<LibraryKey, BlazeJarLibrary> buildLibraries(
WorkspaceBuilder workspaceBuilder,
RuleMap ruleMap,
List<RuleIdeInfo> libraryRules,
List<RuleIdeInfo> protoLibraries) {
// Build library maps
- Multimap<Label, BlazeJarLibrary> labelToLibrary = ArrayListMultimap.create();
+ Multimap<RuleKey, BlazeJarLibrary> ruleKeyToLibrary = ArrayListMultimap.create();
Map<String, BlazeJarLibrary> jdepsPathToLibrary = Maps.newHashMap();
// Add any output jars from source rules
- for (Label label : workspaceBuilder.outputJarsFromSourceRules.keySet()) {
- Collection<BlazeJarLibrary> jars = workspaceBuilder.outputJarsFromSourceRules.get(label);
- labelToLibrary.putAll(label, jars);
+ for (RuleKey key : workspaceBuilder.outputJarsFromSourceRules.keySet()) {
+ Collection<BlazeJarLibrary> jars = workspaceBuilder.outputJarsFromSourceRules.get(key);
+ ruleKeyToLibrary.putAll(key, jars);
for (BlazeJarLibrary library : jars) {
addLibraryToJdeps(jdepsPathToLibrary, library);
}
@@ -236,10 +167,10 @@
Collection<BlazeJarLibrary> libraries =
allJars
.stream()
- .map(library -> new BlazeJarLibrary(library, rule.label))
+ .map(library -> new BlazeJarLibrary(library, rule.key))
.collect(Collectors.toList());
- labelToLibrary.putAll(rule.label, libraries);
+ ruleKeyToLibrary.putAll(rule.key, libraries);
for (BlazeJarLibrary library : libraries) {
addLibraryToJdeps(jdepsPathToLibrary, library);
}
@@ -256,7 +187,7 @@
protoLibraryLegacyInfo.jarsV1,
protoLibraryLegacyInfo.jarsMutable,
protoLibraryLegacyInfo.jarsImmutable)) {
- addLibraryToJdeps(jdepsPathToLibrary, new BlazeJarLibrary(libraryArtifact, rule.label));
+ addLibraryToJdeps(jdepsPathToLibrary, new BlazeJarLibrary(libraryArtifact, rule.key));
}
}
@@ -271,8 +202,8 @@
}
// Collect jars referenced by direct deps from your working set
- for (Label deps : workspaceBuilder.directDeps) {
- for (BlazeJarLibrary library : labelToLibrary.get(deps)) {
+ for (RuleKey deps : workspaceBuilder.directDeps) {
+ for (BlazeJarLibrary library : ruleKeyToLibrary.get(deps)) {
result.put(library.key, library);
}
}
@@ -290,11 +221,11 @@
private void addProtoLegacyLibrariesFromDirectDeps(
WorkspaceBuilder workspaceBuilder, RuleMap ruleMap, Map<LibraryKey, BlazeJarLibrary> result) {
- List<Label> version1Roots = Lists.newArrayList();
- List<Label> immutableRoots = Lists.newArrayList();
- List<Label> mutableRoots = Lists.newArrayList();
- for (Label label : workspaceBuilder.directDeps) {
- RuleIdeInfo rule = ruleMap.get(label);
+ List<RuleKey> version1Roots = Lists.newArrayList();
+ List<RuleKey> immutableRoots = Lists.newArrayList();
+ List<RuleKey> mutableRoots = Lists.newArrayList();
+ for (RuleKey ruleKey : workspaceBuilder.directDeps) {
+ RuleIdeInfo rule = ruleMap.get(ruleKey);
if (rule == null) {
continue;
}
@@ -304,17 +235,17 @@
}
switch (protoLibraryLegacyInfo.apiFlavor) {
case VERSION_1:
- version1Roots.add(label);
+ version1Roots.add(ruleKey);
break;
case IMMUTABLE:
- immutableRoots.add(label);
+ immutableRoots.add(ruleKey);
break;
case MUTABLE:
- mutableRoots.add(label);
+ mutableRoots.add(ruleKey);
break;
case BOTH:
- mutableRoots.add(label);
- immutableRoots.add(label);
+ mutableRoots.add(ruleKey);
+ immutableRoots.add(ruleKey);
break;
default:
// Can't happen
@@ -333,15 +264,15 @@
private void addProtoLegacyLibrariesFromDirectDepsForFlavor(
RuleMap ruleMap,
ProtoLibraryLegacyInfo.ApiFlavor apiFlavor,
- List<Label> roots,
+ List<RuleKey> roots,
Map<LibraryKey, BlazeJarLibrary> result) {
- Set<Label> seen = Sets.newHashSet();
+ Set<RuleKey> seen = Sets.newHashSet();
while (!roots.isEmpty()) {
- Label label = roots.remove(roots.size() - 1);
- if (!seen.add(label)) {
+ RuleKey ruleKey = roots.remove(roots.size() - 1);
+ if (!seen.add(ruleKey)) {
continue;
}
- RuleIdeInfo rule = ruleMap.get(label);
+ RuleIdeInfo rule = ruleMap.get(ruleKey);
if (rule == null) {
continue;
}
@@ -368,12 +299,14 @@
if (libraries != null) {
for (LibraryArtifact libraryArtifact : libraries) {
- BlazeJarLibrary library = new BlazeJarLibrary(libraryArtifact, label);
+ BlazeJarLibrary library = new BlazeJarLibrary(libraryArtifact, ruleKey);
result.put(library.key, library);
}
}
- roots.addAll(rule.dependencies);
+ for (Label dep : rule.dependencies) {
+ roots.add(RuleKey.forDependency(rule, dep));
+ }
}
}
@@ -399,52 +332,54 @@
return;
}
- Label label = rule.label;
- Collection<String> jars = jdepsMap.getDependenciesForRule(label);
+ RuleKey ruleKey = rule.key;
+ Collection<String> jars = jdepsMap.getDependenciesForRule(ruleKey);
if (jars != null) {
workspaceBuilder.jdeps.addAll(jars);
}
// Add all deps if this rule is in the current working set
if (workingSet == null || workingSet.isRuleInWorkingSet(rule)) {
- workspaceBuilder.directDeps.add(
- label); // Add self, so we pick up our own gen jars if in working set
- workspaceBuilder.directDeps.addAll(rule.dependencies);
+ // Add self, so we pick up our own gen jars if in working set
+ workspaceBuilder.directDeps.add(ruleKey);
+ for (Label dep : rule.dependencies) {
+ workspaceBuilder.directDeps.add(RuleKey.forDependency(rule, dep));
+ }
}
for (ArtifactLocation artifactLocation : javaSources) {
if (artifactLocation.isSource()) {
- duplicateSourceDetector.add(label, artifactLocation);
- workspaceBuilder.sourceArtifacts.add(new SourceArtifact(label, artifactLocation));
- workspaceBuilder.addedSourceFiles.add(artifactLocation.getFile());
+ duplicateSourceDetector.add(ruleKey, artifactLocation);
+ workspaceBuilder.sourceArtifacts.add(new SourceArtifact(ruleKey, artifactLocation));
+ workspaceBuilder.addedSourceFiles.add(artifactLocation);
}
}
ArtifactLocation manifest = javaRuleIdeInfo.packageManifest;
if (manifest != null) {
- workspaceBuilder.javaPackageManifests.put(label, manifest);
+ workspaceBuilder.javaPackageManifests.put(ruleKey, manifest);
}
for (LibraryArtifact libraryArtifact : javaRuleIdeInfo.jars) {
ArtifactLocation classJar = libraryArtifact.classJar;
if (classJar != null) {
- workspaceBuilder.buildOutputJars.add(classJar.getFile());
+ workspaceBuilder.buildOutputJars.add(classJar);
}
}
workspaceBuilder.generatedJarsFromSourceRules.addAll(
javaRuleIdeInfo
.generatedJars
.stream()
- .map(libraryArtifact -> new BlazeJarLibrary(libraryArtifact, label))
+ .map(libraryArtifact -> new BlazeJarLibrary(libraryArtifact, ruleKey))
.collect(Collectors.toList()));
if (javaRuleIdeInfo.filteredGenJar != null) {
workspaceBuilder.generatedJarsFromSourceRules.add(
- new BlazeJarLibrary(javaRuleIdeInfo.filteredGenJar, label));
+ new BlazeJarLibrary(javaRuleIdeInfo.filteredGenJar, ruleKey));
}
for (BlazeJavaSyncAugmenter augmenter : augmenters) {
augmenter.addJarsForSourceRule(
rule,
- workspaceBuilder.outputJarsFromSourceRules.get(label),
+ workspaceBuilder.outputJarsFromSourceRules.get(ruleKey),
workspaceBuilder.generatedJarsFromSourceRules);
}
}
@@ -459,14 +394,14 @@
return null;
}
- static class WorkspaceBuilder {
+ private static class WorkspaceBuilder {
Set<String> jdeps = Sets.newHashSet();
- Set<Label> directDeps = Sets.newHashSet();
- Set<File> addedSourceFiles = Sets.newHashSet();
- Multimap<Label, BlazeJarLibrary> outputJarsFromSourceRules = ArrayListMultimap.create();
+ Set<RuleKey> directDeps = Sets.newHashSet();
+ Set<ArtifactLocation> addedSourceFiles = Sets.newHashSet();
+ Multimap<RuleKey, BlazeJarLibrary> outputJarsFromSourceRules = ArrayListMultimap.create();
List<BlazeJarLibrary> generatedJarsFromSourceRules = Lists.newArrayList();
- List<File> buildOutputJars = Lists.newArrayList();
+ List<ArtifactLocation> buildOutputJars = Lists.newArrayList();
List<SourceArtifact> sourceArtifacts = Lists.newArrayList();
- Map<Label, ArtifactLocation> javaPackageManifests = Maps.newHashMap();
+ Map<RuleKey, ArtifactLocation> javaPackageManifests = Maps.newHashMap();
}
}
diff --git a/java/src/com/google/idea/blaze/java/sync/importer/JavaSourceFilter.java b/java/src/com/google/idea/blaze/java/sync/importer/JavaSourceFilter.java
new file mode 100644
index 0000000..0474836
--- /dev/null
+++ b/java/src/com/google/idea/blaze/java/sync/importer/JavaSourceFilter.java
@@ -0,0 +1,115 @@
+/*
+ * 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.java.sync.importer;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
+import com.google.idea.blaze.base.model.primitives.Kind;
+import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.sync.projectview.ProjectViewRuleImportFilter;
+import com.google.idea.common.experiments.BoolExperiment;
+import com.intellij.openapi.project.Project;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/** Segments java rules into source/libraries */
+public class JavaSourceFilter {
+ private static final BoolExperiment NO_EMPTY_SOURCE_RULES =
+ new BoolExperiment("no.empty.source.rules", true);
+
+ final List<RuleIdeInfo> sourceRules;
+ final List<RuleIdeInfo> libraryRules;
+ final List<RuleIdeInfo> protoLibraries;
+ final Map<RuleKey, Collection<ArtifactLocation>> ruleToJavaSources;
+
+ public JavaSourceFilter(
+ Project project,
+ WorkspaceRoot workspaceRoot,
+ ProjectViewSet projectViewSet,
+ RuleMap ruleMap) {
+ ProjectViewRuleImportFilter importFilter =
+ new ProjectViewRuleImportFilter(project, workspaceRoot, projectViewSet);
+ List<RuleIdeInfo> includedRules =
+ ruleMap
+ .rules()
+ .stream()
+ .filter(rule -> !importFilter.excludeTarget(rule))
+ .collect(Collectors.toList());
+
+ List<RuleIdeInfo> javaRules =
+ includedRules
+ .stream()
+ .filter(rule -> rule.javaRuleIdeInfo != null)
+ .collect(Collectors.toList());
+
+ ruleToJavaSources = Maps.newHashMap();
+ for (RuleIdeInfo rule : javaRules) {
+ List<ArtifactLocation> javaSources =
+ rule.sources
+ .stream()
+ .filter(source -> source.getRelativePath().endsWith(".java"))
+ .collect(Collectors.toList());
+ ruleToJavaSources.put(rule.key, javaSources);
+ }
+
+ boolean noEmptySourceRules = NO_EMPTY_SOURCE_RULES.getValue();
+ sourceRules = Lists.newArrayList();
+ libraryRules = Lists.newArrayList();
+ for (RuleIdeInfo rule : javaRules) {
+ boolean importAsSource =
+ importFilter.isSourceRule(rule)
+ && canImportAsSource(rule)
+ && (noEmptySourceRules
+ ? anyNonGeneratedSources(ruleToJavaSources.get(rule.key))
+ : !allSourcesGenerated(ruleToJavaSources.get(rule.key)));
+
+ if (importAsSource) {
+ sourceRules.add(rule);
+ } else {
+ libraryRules.add(rule);
+ }
+ }
+
+ protoLibraries =
+ includedRules
+ .stream()
+ .filter(rule -> rule.kind == Kind.PROTO_LIBRARY)
+ .collect(Collectors.toList());
+ }
+
+ public Iterable<RuleIdeInfo> getSourceRules() {
+ return sourceRules;
+ }
+
+ private boolean canImportAsSource(RuleIdeInfo rule) {
+ return !rule.kindIsOneOf(Kind.JAVA_WRAP_CC, Kind.JAVA_IMPORT);
+ }
+
+ private boolean allSourcesGenerated(Collection<ArtifactLocation> sources) {
+ return !sources.isEmpty() && sources.stream().allMatch(ArtifactLocation::isGenerated);
+ }
+
+ private boolean anyNonGeneratedSources(Collection<ArtifactLocation> sources) {
+ return sources.stream().anyMatch(ArtifactLocation::isSource);
+ }
+}
diff --git a/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsFileReader.java b/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsFileReader.java
index 4570965..c4bdaac 100644
--- a/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsFileReader.java
+++ b/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsFileReader.java
@@ -26,14 +26,14 @@
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.JavaRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
-import com.google.idea.blaze.base.model.RuleMap;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.SyncState;
-import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.prefetch.PrefetchService;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.Scope;
import com.google.idea.blaze.base.scope.output.PrintOutput;
import com.google.idea.blaze.base.scope.scopes.TimingScope;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.repackaged.devtools.build.lib.view.proto.Deps;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -54,20 +54,20 @@
private static final Logger LOG = Logger.getInstance(JdepsFileReader.class);
static class JdepsState implements Serializable {
- private static final long serialVersionUID = 3L;
+ private static final long serialVersionUID = 4L;
private ImmutableMap<File, Long> fileState = null;
- private Map<File, Label> fileToLabelMap = Maps.newHashMap();
- private Map<Label, List<String>> labelToJdeps = Maps.newHashMap();
+ private Map<File, RuleKey> fileToRuleMap = Maps.newHashMap();
+ private Map<RuleKey, List<String>> ruleToJdeps = Maps.newHashMap();
}
private static class Result {
File file;
- Label label;
+ RuleKey ruleKey;
List<String> dependencies;
- public Result(File file, Label label, List<String> dependencies) {
+ public Result(File file, RuleKey ruleKey, List<String> dependencies) {
this.file = file;
- this.label = label;
+ this.ruleKey = ruleKey;
this.dependencies = dependencies;
}
}
@@ -77,7 +77,8 @@
public JdepsMap loadJdepsFiles(
Project project,
BlazeContext parentContext,
- RuleMap ruleMap,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ Iterable<RuleIdeInfo> rulesToLoad,
SyncState.Builder syncStateBuilder,
@Nullable SyncState previousSyncState) {
JdepsState oldState =
@@ -87,30 +88,36 @@
parentContext,
(context) -> {
context.push(new TimingScope("LoadJdepsFiles"));
- return doLoadJdepsFiles(project, context, oldState, ruleMap);
+ return doLoadJdepsFiles(
+ project, context, artifactLocationDecoder, oldState, rulesToLoad);
});
if (jdepsState == null) {
return null;
}
syncStateBuilder.put(JdepsState.class, jdepsState);
- return label -> jdepsState.labelToJdeps.get(label);
+ return ruleKey -> jdepsState.ruleToJdeps.get(ruleKey);
}
private JdepsState doLoadJdepsFiles(
- Project project, BlazeContext context, @Nullable JdepsState oldState, RuleMap ruleMap) {
+ Project project,
+ BlazeContext context,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ @Nullable JdepsState oldState,
+ Iterable<RuleIdeInfo> rulesToLoad) {
JdepsState state = new JdepsState();
if (oldState != null) {
- state.labelToJdeps = Maps.newHashMap(oldState.labelToJdeps);
- state.fileToLabelMap = Maps.newHashMap(oldState.fileToLabelMap);
+ state.ruleToJdeps = Maps.newHashMap(oldState.ruleToJdeps);
+ state.fileToRuleMap = Maps.newHashMap(oldState.fileToRuleMap);
}
- List<File> files = Lists.newArrayList();
- for (RuleIdeInfo ruleIdeInfo : ruleMap.rules()) {
+ Map<File, RuleKey> fileToRuleMap = Maps.newHashMap();
+ for (RuleIdeInfo ruleIdeInfo : rulesToLoad) {
+ assert ruleIdeInfo != null;
JavaRuleIdeInfo javaRuleIdeInfo = ruleIdeInfo.javaRuleIdeInfo;
if (javaRuleIdeInfo != null) {
ArtifactLocation jdepsFile = javaRuleIdeInfo.jdepsFile;
if (jdepsFile != null) {
- files.add(jdepsFile.getFile());
+ fileToRuleMap.put(artifactLocationDecoder.decode(jdepsFile), ruleIdeInfo.key);
}
}
}
@@ -119,7 +126,10 @@
List<File> removedFiles = Lists.newArrayList();
state.fileState =
FileDiffer.updateFiles(
- oldState != null ? oldState.fileState : null, files, updatedFiles, removedFiles);
+ oldState != null ? oldState.fileState : null,
+ fileToRuleMap.keySet(),
+ updatedFiles,
+ removedFiles);
ListenableFuture<?> fetchFuture =
PrefetchService.getInstance().prefetchFiles(project, updatedFiles);
@@ -132,9 +142,9 @@
}
for (File removedFile : removedFiles) {
- Label label = state.fileToLabelMap.remove(removedFile);
- if (label != null) {
- state.labelToJdeps.remove(label);
+ RuleKey ruleKey = state.fileToRuleMap.remove(removedFile);
+ if (ruleKey != null) {
+ state.ruleToJdeps.remove(ruleKey);
}
}
@@ -149,20 +159,18 @@
try (InputStream inputStream = new FileInputStream(updatedFile)) {
Deps.Dependencies dependencies = Deps.Dependencies.parseFrom(inputStream);
if (dependencies != null) {
- if (dependencies.hasRuleLabel()) {
- Label label = new Label(dependencies.getRuleLabel());
- List<String> dependencyStringList = Lists.newArrayList();
- for (Deps.Dependency dependency : dependencies.getDependencyList()) {
- // We only want explicit or implicit deps that were
- // actually resolved by the compiler, not ones that are
- // available for use in the same package
- if (dependency.getKind() == Deps.Dependency.Kind.EXPLICIT
- || dependency.getKind() == Deps.Dependency.Kind.IMPLICIT) {
- dependencyStringList.add(dependency.getPath());
- }
+ List<String> dependencyStringList = Lists.newArrayList();
+ for (Deps.Dependency dependency : dependencies.getDependencyList()) {
+ // We only want explicit or implicit deps that were
+ // actually resolved by the compiler, not ones that are
+ // available for use in the same package
+ if (dependency.getKind() == Deps.Dependency.Kind.EXPLICIT
+ || dependency.getKind() == Deps.Dependency.Kind.IMPLICIT) {
+ dependencyStringList.add(dependency.getPath());
}
- return new Result(updatedFile, label, dependencyStringList);
}
+ RuleKey ruleKey = fileToRuleMap.get(updatedFile);
+ return new Result(updatedFile, ruleKey, dependencyStringList);
}
} catch (FileNotFoundException e) {
LOG.info("Could not open jdeps file: " + updatedFile);
@@ -173,8 +181,8 @@
try {
for (Result result : Futures.allAsList(futures).get()) {
if (result != null) {
- state.fileToLabelMap.put(result.file, result.label);
- state.labelToJdeps.put(result.label, result.dependencies);
+ state.fileToRuleMap.put(result.file, result.ruleKey);
+ state.ruleToJdeps.put(result.ruleKey, result.dependencies);
}
}
context.output(
diff --git a/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsMap.java b/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsMap.java
index 73ae6a2..32b5452 100644
--- a/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsMap.java
+++ b/java/src/com/google/idea/blaze/java/sync/jdeps/JdepsMap.java
@@ -15,9 +15,8 @@
*/
package com.google.idea.blaze.java.sync.jdeps;
-import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import java.util.List;
-import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/** Map of rule -> jdeps dependencies. */
@@ -31,5 +30,5 @@
* <p>If the rule doesn't have source or otherwise wasn't instrumented, null is returned.
*/
@Nullable
- List<String> getDependenciesForRule(@NotNull Label label);
+ List<String> getDependenciesForRule(RuleKey ruleKey);
}
diff --git a/java/src/com/google/idea/blaze/java/sync/model/BlazeJarLibrary.java b/java/src/com/google/idea/blaze/java/sync/model/BlazeJarLibrary.java
index 2470e63..02bee44 100644
--- a/java/src/com/google/idea/blaze/java/sync/model/BlazeJarLibrary.java
+++ b/java/src/com/google/idea/blaze/java/sync/model/BlazeJarLibrary.java
@@ -17,7 +17,8 @@
import com.google.common.base.Objects;
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
-import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.java.libraries.JarCache;
import com.google.idea.blaze.java.libraries.SourceJarManager;
import com.google.idea.blaze.java.settings.BlazeJavaUserSettings;
@@ -30,22 +31,25 @@
/** An immutable reference to a .jar required by a rule. */
@Immutable
public final class BlazeJarLibrary extends BlazeLibrary {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = 2L;
public final LibraryArtifact libraryArtifact;
- public final Label originatingRule;
+ public final RuleKey originatingRule;
- public BlazeJarLibrary(LibraryArtifact libraryArtifact, Label originatingRule) {
- super(LibraryKey.fromJarFile(libraryArtifact.jarForIntellijLibrary().getFile()));
+ public BlazeJarLibrary(LibraryArtifact libraryArtifact, RuleKey originatingRule) {
+ super(LibraryKey.fromJarFile(libraryArtifact.jarForIntellijLibrary()));
this.libraryArtifact = libraryArtifact;
this.originatingRule = originatingRule;
}
@Override
- public void modifyLibraryModel(Project project, Library.ModifiableModel libraryModel) {
+ public void modifyLibraryModel(
+ Project project,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ Library.ModifiableModel libraryModel) {
JarCache jarCache = JarCache.getInstance(project);
- File jar = jarCache.getCachedJar(this);
+ File jar = jarCache.getCachedJar(artifactLocationDecoder, this);
libraryModel.addRoot(pathToUrl(jar), OrderRootType.CLASSES);
boolean attachSourcesByDefault =
@@ -53,7 +57,7 @@
SourceJarManager sourceJarManager = SourceJarManager.getInstance(project);
boolean attachSourceJar = attachSourcesByDefault || sourceJarManager.hasSourceJarAttached(key);
if (attachSourceJar && libraryArtifact.sourceJar != null) {
- File sourceJar = jarCache.getCachedSourceJar(this);
+ File sourceJar = jarCache.getCachedSourceJar(artifactLocationDecoder, this);
if (sourceJar != null) {
libraryModel.addRoot(pathToUrl(sourceJar), OrderRootType.SOURCES);
}
diff --git a/java/src/com/google/idea/blaze/java/sync/model/BlazeJavaImportResult.java b/java/src/com/google/idea/blaze/java/sync/model/BlazeJavaImportResult.java
index f033772..eb3c3c8 100644
--- a/java/src/com/google/idea/blaze/java/sync/model/BlazeJavaImportResult.java
+++ b/java/src/com/google/idea/blaze/java/sync/model/BlazeJavaImportResult.java
@@ -19,7 +19,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import java.io.File;
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import java.io.Serializable;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@@ -27,19 +27,19 @@
/** The result of a blaze import operation. */
@Immutable
public class BlazeJavaImportResult implements Serializable {
- private static final long serialVersionUID = 3L;
+ private static final long serialVersionUID = 4L;
public final ImmutableList<BlazeContentEntry> contentEntries;
public final ImmutableMap<LibraryKey, BlazeJarLibrary> libraries;
- public final ImmutableCollection<File> buildOutputJars;
- public final ImmutableSet<File> javaSourceFiles;
+ public final ImmutableCollection<ArtifactLocation> buildOutputJars;
+ public final ImmutableSet<ArtifactLocation> javaSourceFiles;
@Nullable public final String sourceVersion;
public BlazeJavaImportResult(
ImmutableList<BlazeContentEntry> contentEntries,
ImmutableMap<LibraryKey, BlazeJarLibrary> libraries,
- ImmutableCollection<File> buildOutputJars,
- ImmutableSet<File> javaSourceFiles,
+ ImmutableCollection<ArtifactLocation> buildOutputJars,
+ ImmutableSet<ArtifactLocation> javaSourceFiles,
@Nullable String sourceVersion) {
this.contentEntries = contentEntries;
this.libraries = libraries;
diff --git a/java/src/com/google/idea/blaze/java/sync/model/BlazeLibrary.java b/java/src/com/google/idea/blaze/java/sync/model/BlazeLibrary.java
index f84fc4c..f289717 100644
--- a/java/src/com/google/idea/blaze/java/sync/model/BlazeLibrary.java
+++ b/java/src/com/google/idea/blaze/java/sync/model/BlazeLibrary.java
@@ -16,6 +16,7 @@
package com.google.idea.blaze.java.sync.model;
import com.google.common.base.Objects;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.io.FileUtil;
@@ -61,7 +62,10 @@
return Objects.equal(key, that.key);
}
- public abstract void modifyLibraryModel(Project project, Library.ModifiableModel libraryModel);
+ public abstract void modifyLibraryModel(
+ Project project,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ Library.ModifiableModel libraryModel);
protected static String pathToUrl(File path) {
String name = path.getName();
diff --git a/java/src/com/google/idea/blaze/java/sync/model/LibraryKey.java b/java/src/com/google/idea/blaze/java/sync/model/LibraryKey.java
index 8496a31..fe19973 100644
--- a/java/src/com/google/idea/blaze/java/sync/model/LibraryKey.java
+++ b/java/src/com/google/idea/blaze/java/sync/model/LibraryKey.java
@@ -15,34 +15,33 @@
*/
package com.google.idea.blaze.java.sync.model;
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.io.FileUtil;
import java.io.File;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
-import org.jetbrains.annotations.NotNull;
/** Uniquely identifies a library as imported into IntellJ. */
@Immutable
public final class LibraryKey implements Serializable {
public static final long serialVersionUID = 1L;
- @NotNull private final String name;
+ private final String name;
- @NotNull
- public static LibraryKey fromJarFile(@NotNull File jarFile) {
- int parentHash = jarFile.getParent().hashCode();
+ public static LibraryKey fromJarFile(ArtifactLocation artifactLocation) {
+ File jarFile = new File(artifactLocation.getRelativePath());
+ String parent = jarFile.getParent();
+ int parentHash = parent != null ? parent.hashCode() : jarFile.hashCode();
String name = FileUtil.getNameWithoutExtension(jarFile) + "_" + Integer.toHexString(parentHash);
return new LibraryKey(name);
}
- @NotNull
public static LibraryKey forResourceLibrary() {
return new LibraryKey("external_resources_library");
}
- @NotNull
- public static LibraryKey fromIntelliJLibrary(@NotNull Library library) {
+ public static LibraryKey fromIntelliJLibrary(Library library) {
String name = library.getName();
if (name == null) {
throw new IllegalArgumentException("Null library name");
@@ -50,12 +49,11 @@
return fromIntelliJLibraryName(name);
}
- @NotNull
- public static LibraryKey fromIntelliJLibraryName(@NotNull String name) {
+ public static LibraryKey fromIntelliJLibraryName(String name) {
return new LibraryKey(name);
}
- LibraryKey(@NotNull String name) {
+ LibraryKey(String name) {
this.name = name;
}
diff --git a/java/src/com/google/idea/blaze/java/sync/projectstructure/LibraryEditor.java b/java/src/com/google/idea/blaze/java/sync/projectstructure/LibraryEditor.java
index ea197ed..aa6ba5e 100644
--- a/java/src/com/google/idea/blaze/java/sync/projectstructure/LibraryEditor.java
+++ b/java/src/com/google/idea/blaze/java/sync/projectstructure/LibraryEditor.java
@@ -19,6 +19,7 @@
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.PrintOutput;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.java.sync.BlazeJavaSyncAugmenter;
import com.google.idea.blaze.java.sync.model.BlazeLibrary;
import com.google.idea.blaze.java.sync.model.LibraryKey;
@@ -62,7 +63,12 @@
LibraryTable.ModifiableModel libraryTableModel = libraryTable.getModifiableModel();
try {
for (BlazeLibrary library : libraries) {
- updateLibrary(project, libraryTable, libraryTableModel, library);
+ updateLibrary(
+ project,
+ blazeProjectData.artifactLocationDecoder,
+ libraryTable,
+ libraryTableModel,
+ library);
}
// Garbage collect unused libraries
@@ -85,6 +91,7 @@
public static void updateLibrary(
Project project,
+ ArtifactLocationDecoder artifactLocationDecoder,
LibraryTable libraryTable,
LibraryTable.ModifiableModel libraryTableModel,
BlazeLibrary blazeLibrary) {
@@ -105,7 +112,7 @@
}
}
try {
- blazeLibrary.modifyLibraryModel(project, libraryModel);
+ blazeLibrary.modifyLibraryModel(project, artifactLocationDecoder, libraryModel);
} finally {
libraryModel.commit();
}
diff --git a/java/src/com/google/idea/blaze/java/sync/source/FilePathJavaPackageReader.java b/java/src/com/google/idea/blaze/java/sync/source/FilePathJavaPackageReader.java
index 99e3c66..0c1265a 100644
--- a/java/src/com/google/idea/blaze/java/sync/source/FilePathJavaPackageReader.java
+++ b/java/src/com/google/idea/blaze/java/sync/source/FilePathJavaPackageReader.java
@@ -17,12 +17,16 @@
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.base.util.PackagePrefixCalculator;
/** Gets the package from a java file by its file path alone (i.e. without opening the file). */
public final class FilePathJavaPackageReader extends JavaPackageReader {
@Override
- public String getDeclaredPackageOfJavaFile(BlazeContext context, SourceArtifact sourceArtifact) {
+ public String getDeclaredPackageOfJavaFile(
+ BlazeContext context,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ SourceArtifact sourceArtifact) {
String directory = sourceArtifact.artifactLocation.getRelativePath();
int i = directory.lastIndexOf('/');
if (i >= 0) {
diff --git a/java/src/com/google/idea/blaze/java/sync/source/JavaPackageReader.java b/java/src/com/google/idea/blaze/java/sync/source/JavaPackageReader.java
index 9c1f037..ee190e9 100644
--- a/java/src/com/google/idea/blaze/java/sync/source/JavaPackageReader.java
+++ b/java/src/com/google/idea/blaze/java/sync/source/JavaPackageReader.java
@@ -16,10 +16,14 @@
package com.google.idea.blaze.java.sync.source;
import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import javax.annotation.Nullable;
/** Reads java packages from files. */
public abstract class JavaPackageReader {
@Nullable
- abstract String getDeclaredPackageOfJavaFile(BlazeContext context, SourceArtifact sourceArtifact);
+ abstract String getDeclaredPackageOfJavaFile(
+ BlazeContext context,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ SourceArtifact sourceArtifact);
}
diff --git a/java/src/com/google/idea/blaze/java/sync/source/JavaSourcePackageReader.java b/java/src/com/google/idea/blaze/java/sync/source/JavaSourcePackageReader.java
index 0f3eca0..f67f76c 100644
--- a/java/src/com/google/idea/blaze/java/sync/source/JavaSourcePackageReader.java
+++ b/java/src/com/google/idea/blaze/java/sync/source/JavaSourcePackageReader.java
@@ -15,9 +15,12 @@
*/
package com.google.idea.blaze.java.sync.source;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import com.google.idea.blaze.base.io.InputStreamProvider;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.output.IssueOutput;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import java.io.BufferedReader;
@@ -44,14 +47,17 @@
@Override
@Nullable
- public String getDeclaredPackageOfJavaFile(BlazeContext context, SourceArtifact sourceArtifact) {
+ public String getDeclaredPackageOfJavaFile(
+ BlazeContext context,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ SourceArtifact sourceArtifact) {
if (sourceArtifact.artifactLocation.isGenerated()) {
return null;
}
InputStreamProvider inputStreamProvider = InputStreamProvider.getInstance();
- File sourceFile = sourceArtifact.artifactLocation.getFile();
+ File sourceFile = artifactLocationDecoder.decode(sourceArtifact.artifactLocation);
try (InputStream javaInputStream = inputStreamProvider.getFile(sourceFile)) {
- BufferedReader javaReader = new BufferedReader(new InputStreamReader(javaInputStream));
+ BufferedReader javaReader = new BufferedReader(new InputStreamReader(javaInputStream, UTF_8));
String javaLine;
while ((javaLine = javaReader.readLine()) != null) {
diff --git a/java/src/com/google/idea/blaze/java/sync/source/ManifestFilePackageReader.java b/java/src/com/google/idea/blaze/java/sync/source/ManifestFilePackageReader.java
index 726d60a..96d1177 100644
--- a/java/src/com/google/idea/blaze/java/sync/source/ManifestFilePackageReader.java
+++ b/java/src/com/google/idea/blaze/java/sync/source/ManifestFilePackageReader.java
@@ -15,25 +15,31 @@
*/
package com.google.idea.blaze.java.sync.source;
-import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import java.util.Map;
import javax.annotation.Nullable;
class ManifestFilePackageReader extends JavaPackageReader {
- private final Map<Label, Map<String, String>> manifestMap;
+ private final Map<RuleKey, Map<ArtifactLocation, String>> manifestMap;
- public ManifestFilePackageReader(Map<Label, Map<String, String>> manifestMap) {
+ public ManifestFilePackageReader(Map<RuleKey, Map<ArtifactLocation, String>> manifestMap) {
this.manifestMap = manifestMap;
}
@Nullable
@Override
- String getDeclaredPackageOfJavaFile(BlazeContext context, SourceArtifact sourceArtifact) {
- Map<String, String> manifestMapForRule = manifestMap.get(sourceArtifact.originatingRule);
+ String getDeclaredPackageOfJavaFile(
+ BlazeContext context,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ SourceArtifact sourceArtifact) {
+ Map<ArtifactLocation, String> manifestMapForRule =
+ manifestMap.get(sourceArtifact.originatingRule);
if (manifestMapForRule != null) {
- return manifestMapForRule.get(sourceArtifact.artifactLocation.getFile().getPath());
+ return manifestMapForRule.get(sourceArtifact.artifactLocation);
}
return null;
}
diff --git a/java/src/com/google/idea/blaze/java/sync/source/PackageManifestReader.java b/java/src/com/google/idea/blaze/java/sync/source/PackageManifestReader.java
index 61ec202..96a0813 100644
--- a/java/src/com/google/idea/blaze/java/sync/source/PackageManifestReader.java
+++ b/java/src/com/google/idea/blaze/java/sync/source/PackageManifestReader.java
@@ -24,8 +24,8 @@
import com.google.idea.blaze.base.async.FutureUtil;
import com.google.idea.blaze.base.filecache.FileDiffer;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.io.InputStreamProvider;
-import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.prefetch.PrefetchService;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
@@ -41,7 +41,6 @@
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
-import javax.annotation.Nullable;
/** Reads package manifests. */
public class PackageManifestReader {
@@ -53,22 +52,22 @@
private ImmutableMap<File, Long> fileDiffState;
- private Map<File, Label> fileToLabelMap = Maps.newHashMap();
- private final Map<Label, Map<String, String>> manifestMap = Maps.newConcurrentMap();
+ private Map<File, RuleKey> fileToLabelMap = Maps.newHashMap();
+ private final Map<RuleKey, Map<ArtifactLocation, String>> manifestMap = Maps.newConcurrentMap();
/** @return A map from java source absolute file path to declared package string. */
- public Map<Label, Map<String, String>> readPackageManifestFiles(
+ public Map<RuleKey, Map<ArtifactLocation, String>> readPackageManifestFiles(
Project project,
BlazeContext context,
ArtifactLocationDecoder decoder,
- Map<Label, ArtifactLocation> javaPackageManifests,
+ Map<RuleKey, ArtifactLocation> javaPackageManifests,
ListeningExecutorService executorService) {
- Map<File, Label> fileToLabelMap = Maps.newHashMap();
- for (Map.Entry<Label, ArtifactLocation> entry : javaPackageManifests.entrySet()) {
- Label label = entry.getKey();
- File file = entry.getValue().getFile();
- fileToLabelMap.put(file, label);
+ Map<File, RuleKey> fileToLabelMap = Maps.newHashMap();
+ for (Map.Entry<RuleKey, ArtifactLocation> entry : javaPackageManifests.entrySet()) {
+ RuleKey key = entry.getKey();
+ File file = decoder.decode(entry.getValue());
+ fileToLabelMap.put(file, key);
}
List<File> updatedFiles = Lists.newArrayList();
List<File> removedFiles = Lists.newArrayList();
@@ -90,15 +89,15 @@
futures.add(
executorService.submit(
() -> {
- Map<String, String> manifest = parseManifestFile(decoder, file);
+ Map<ArtifactLocation, String> manifest = parseManifestFile(file);
manifestMap.put(fileToLabelMap.get(file), manifest);
return null;
}));
}
for (File file : removedFiles) {
- Label label = this.fileToLabelMap.get(file);
- if (label != null) {
- manifestMap.remove(label);
+ RuleKey key = this.fileToLabelMap.get(file);
+ if (key != null) {
+ manifestMap.remove(key);
}
}
this.fileToLabelMap = fileToLabelMap;
@@ -112,19 +111,22 @@
return manifestMap;
}
- protected Map<String, String> parseManifestFile(
- ArtifactLocationDecoder decoder, File packageManifest) {
- Map<String, String> outputMap = Maps.newHashMap();
+ protected Map<ArtifactLocation, String> parseManifestFile(File packageManifest) {
+ Map<ArtifactLocation, String> outputMap = Maps.newHashMap();
InputStreamProvider inputStreamProvider = InputStreamProvider.getInstance();
try (InputStream input = inputStreamProvider.getFile(packageManifest)) {
try (BufferedInputStream bufferedInputStream = new BufferedInputStream(input)) {
PackageManifest proto = PackageManifest.parseFrom(bufferedInputStream);
for (JavaSourcePackage source : proto.getSourcesList()) {
- String absPath = getAbsolutePath(decoder, source);
- if (absPath != null) {
- outputMap.put(absPath, source.getPackageString());
- }
+ ArtifactLocation artifactLocation =
+ ArtifactLocation.builder()
+ .setRootExecutionPathFragment(
+ source.getArtifactLocation().getRootExecutionPathFragment())
+ .setRelativePath(source.getArtifactLocation().getRelativePath())
+ .setIsSource(source.getArtifactLocation().getIsSource())
+ .build();
+ outputMap.put(artifactLocation, source.getPackageString());
}
}
return outputMap;
@@ -133,17 +135,4 @@
return outputMap;
}
}
-
- /**
- * Returns null if the artifact location file can't be found, presumably because it's been removed
- * from the file system since the blaze build.
- */
- @Nullable
- private static String getAbsolutePath(ArtifactLocationDecoder decoder, JavaSourcePackage source) {
- ArtifactLocation location = decoder.decode(source.getArtifactLocation());
- if (location == null) {
- return null;
- }
- return location.getFile().getAbsolutePath();
- }
}
diff --git a/java/src/com/google/idea/blaze/java/sync/source/SourceArtifact.java b/java/src/com/google/idea/blaze/java/sync/source/SourceArtifact.java
index 37e35bd..6c00f09 100644
--- a/java/src/com/google/idea/blaze/java/sync/source/SourceArtifact.java
+++ b/java/src/com/google/idea/blaze/java/sync/source/SourceArtifact.java
@@ -16,27 +16,27 @@
package com.google.idea.blaze.java.sync.source;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
-import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
/** Pairing of rule and source artifact. */
public class SourceArtifact {
- public final Label originatingRule;
+ public final RuleKey originatingRule;
public final ArtifactLocation artifactLocation;
- public SourceArtifact(Label originatingRule, ArtifactLocation artifactLocation) {
+ public SourceArtifact(RuleKey originatingRule, ArtifactLocation artifactLocation) {
this.originatingRule = originatingRule;
this.artifactLocation = artifactLocation;
}
- public static Builder builder(Label originatingRule) {
+ public static Builder builder(RuleKey originatingRule) {
return new Builder(originatingRule);
}
static class Builder {
- Label originatingRule;
+ RuleKey originatingRule;
ArtifactLocation artifactLocation;
- Builder(Label originatingRule) {
+ Builder(RuleKey originatingRule) {
this.originatingRule = originatingRule;
}
diff --git a/java/src/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculator.java b/java/src/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculator.java
index c4d992c..2fc3b21 100644
--- a/java/src/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculator.java
+++ b/java/src/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculator.java
@@ -34,7 +34,7 @@
import com.google.common.util.concurrent.MoreExecutors;
import com.google.idea.blaze.base.async.executor.TransientExecutor;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
-import com.google.idea.blaze.base.model.primitives.Label;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
@@ -85,14 +85,14 @@
ArtifactLocationDecoder artifactLocationDecoder,
Collection<WorkspacePath> rootDirectories,
Collection<SourceArtifact> sources,
- Map<Label, ArtifactLocation> javaPackageManifests) {
+ Map<RuleKey, ArtifactLocation> javaPackageManifests) {
ManifestFilePackageReader manifestFilePackageReader =
Scope.push(
context,
(childContext) -> {
childContext.push(new TimingScope("ReadPackageManifests"));
- Map<Label, Map<String, String>> manifestMap =
+ Map<RuleKey, Map<ArtifactLocation, String>> manifestMap =
PackageManifestReader.getInstance()
.readPackageManifestFiles(
project,
@@ -125,8 +125,9 @@
ImmutableList<BlazeSourceDirectory> sourceDirectories =
calculateSourceDirectoriesForContentRoot(
context,
- sourceTestConfig,
workspaceRoot,
+ artifactLocationDecoder,
+ sourceTestConfig,
workspacePath,
sourcesUnderDirectoryRoot.get(workspacePath),
javaPackageReaders);
@@ -168,13 +169,13 @@
if (foundWorkspacePath != null) {
result.put(foundWorkspacePath, sourceArtifact);
} else if (sourceArtifact.artifactLocation.isSource()) {
- File sourceFile = sourceArtifact.artifactLocation.getFile();
+ ArtifactLocation sourceFile = sourceArtifact.artifactLocation;
String message =
String.format(
"Did not add %s. You're probably using a java file from outside the workspace"
+ " that has been exported using export_files. Don't do that.",
sourceFile);
- IssueOutput.warn(message).inFile(sourceFile).submit(context);
+ IssueOutput.warn(message).submit(context);
}
}
return result;
@@ -193,8 +194,9 @@
/** Calculates all source directories for a single content root. */
private ImmutableList<BlazeSourceDirectory> calculateSourceDirectoriesForContentRoot(
BlazeContext context,
- SourceTestConfig sourceTestConfig,
WorkspaceRoot workspaceRoot,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ SourceTestConfig sourceTestConfig,
WorkspacePath directoryRoot,
Collection<SourceArtifact> sourceArtifacts,
Collection<JavaPackageReader> javaPackageReaders) {
@@ -213,6 +215,7 @@
calculateJavaSourceDirectories(
context,
workspaceRoot,
+ artifactLocationDecoder,
directoryRoot,
sourceTestConfig,
javaArtifacts,
@@ -227,6 +230,7 @@
private void calculateJavaSourceDirectories(
BlazeContext context,
WorkspaceRoot workspaceRoot,
+ ArtifactLocationDecoder artifactLocationDecoder,
WorkspacePath directoryRoot,
SourceTestConfig sourceTestConfig,
Collection<SourceArtifact> javaArtifacts,
@@ -240,7 +244,9 @@
for (final SourceArtifact sourceArtifact : javaArtifacts) {
ListenableFuture<SourceRoot> future =
executorService.submit(
- () -> sourceRootForJavaSource(context, sourceArtifact, javaPackageReaders));
+ () ->
+ sourceRootForJavaSource(
+ context, artifactLocationDecoder, sourceArtifact, javaPackageReaders));
sourceRootFutures.add(future);
}
try {
@@ -443,23 +449,25 @@
}
@Nullable
- private static SourceRoot sourceRootForJavaSource(
+ private SourceRoot sourceRootForJavaSource(
BlazeContext context,
+ ArtifactLocationDecoder artifactLocationDecoder,
SourceArtifact sourceArtifact,
Collection<JavaPackageReader> javaPackageReaders) {
- File javaFile = sourceArtifact.artifactLocation.getFile();
-
String declaredPackage = null;
for (JavaPackageReader reader : javaPackageReaders) {
- declaredPackage = reader.getDeclaredPackageOfJavaFile(context, sourceArtifact);
+ declaredPackage =
+ reader.getDeclaredPackageOfJavaFile(context, artifactLocationDecoder, sourceArtifact);
if (declaredPackage != null) {
break;
}
}
if (declaredPackage == null) {
- IssueOutput.warn("Failed to inspect the package name of java source file: " + javaFile)
- .inFile(javaFile)
+ IssueOutput.warn(
+ "Failed to inspect the package name of java source file: "
+ + sourceArtifact.artifactLocation)
+ .inFile(artifactLocationDecoder.decode(sourceArtifact.artifactLocation))
.submit(context);
return null;
}
diff --git a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusClassNodeDecorator.java b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusClassNodeDecorator.java
index 6ffabc2..01d7f40 100644
--- a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusClassNodeDecorator.java
+++ b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusClassNodeDecorator.java
@@ -48,7 +48,7 @@
}
Project project = node.getProject();
- if (SyncStatusHelper.isUnsynced(project, virtualFile)) {
+ if (SyncStatusHelper.getInstance(project).isUnsynced(virtualFile)) {
data.clearText();
data.addText(psiClass.getName(), SimpleTextAttributes.GRAY_ATTRIBUTES);
data.addText(" (unsynced)", SimpleTextAttributes.GRAY_ATTRIBUTES);
diff --git a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabColorProvider.java b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabColorProvider.java
index ad8e396..91234b1 100644
--- a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabColorProvider.java
+++ b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabColorProvider.java
@@ -31,7 +31,8 @@
@Nullable
@Override
public Color getEditorTabColor(@NotNull Project project, @NotNull VirtualFile file) {
- if (file.getName().endsWith(".java") && SyncStatusHelper.isUnsynced(project, file)) {
+ if (file.getName().endsWith(".java")
+ && SyncStatusHelper.getInstance(project).isUnsynced(file)) {
return UNSYNCED_COLOR;
}
return null;
diff --git a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabTitleProvider.java b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabTitleProvider.java
index fce5c89..aa96de8 100644
--- a/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabTitleProvider.java
+++ b/java/src/com/google/idea/blaze/java/syncstatus/BlazeJavaSyncStatusEditorTabTitleProvider.java
@@ -25,7 +25,7 @@
@Nullable
@Override
public String getEditorTabTitle(Project project, VirtualFile file) {
- if (file.getName().endsWith("java") && SyncStatusHelper.isUnsynced(project, file)) {
+ if (file.getName().endsWith("java") && SyncStatusHelper.getInstance(project).isUnsynced(file)) {
return file.getPresentableName() + " (unsynced)";
}
return null;
diff --git a/java/src/com/google/idea/blaze/java/syncstatus/SyncStatusHelper.java b/java/src/com/google/idea/blaze/java/syncstatus/SyncStatusHelper.java
index 2ea5884..74fc43f 100644
--- a/java/src/com/google/idea/blaze/java/syncstatus/SyncStatusHelper.java
+++ b/java/src/com/google/idea/blaze/java/syncstatus/SyncStatusHelper.java
@@ -15,29 +15,57 @@
*/
package com.google.idea.blaze.java.syncstatus;
+import com.google.common.collect.ImmutableSet;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.base.projectview.ProjectViewSet;
+import com.google.idea.blaze.base.scope.BlazeContext;
+import com.google.idea.blaze.base.settings.BlazeImportSettings;
+import com.google.idea.blaze.base.sync.SyncListener;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.java.sync.model.BlazeJavaSyncData;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import java.io.File;
+import java.util.Set;
class SyncStatusHelper {
- static boolean isUnsynced(Project project, VirtualFile virtualFile) {
- BlazeProjectData blazeProjectData =
- BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
- if (blazeProjectData == null) {
- return false;
- }
- BlazeJavaSyncData syncData = blazeProjectData.syncState.get(BlazeJavaSyncData.class);
- if (syncData == null) {
- return false;
- }
+ static SyncStatusHelper getInstance(Project project) {
+ return ServiceManager.getService(project, SyncStatusHelper.class);
+ }
+
+ private Set<File> syncedJavaFiles = ImmutableSet.of();
+
+ boolean isUnsynced(VirtualFile virtualFile) {
if (!virtualFile.isInLocalFileSystem()) {
return false;
}
-
File file = new File(virtualFile.getPath());
- return !syncData.importResult.javaSourceFiles.contains(file);
+ return !syncedJavaFiles.contains(file);
+ }
+
+ void refresh(BlazeProjectData blazeProjectData) {
+ BlazeJavaSyncData syncData = blazeProjectData.syncState.get(BlazeJavaSyncData.class);
+ if (syncData == null) {
+ return;
+ }
+ ArtifactLocationDecoder artifactLocationDecoder = blazeProjectData.artifactLocationDecoder;
+ syncedJavaFiles =
+ ImmutableSet.<File>builder()
+ .addAll(artifactLocationDecoder.decodeAll(syncData.importResult.javaSourceFiles))
+ .build();
+ }
+
+ static class UpdateSyncStatusMap extends SyncListener.Adapter {
+ @Override
+ public void onSyncComplete(
+ Project project,
+ BlazeContext context,
+ BlazeImportSettings importSettings,
+ ProjectViewSet projectViewSet,
+ BlazeProjectData blazeProjectData,
+ SyncResult syncResult) {
+ getInstance(project).refresh(blazeProjectData);
+ }
}
}
diff --git a/java/tests/integrationtests/com/google/idea/blaze/java/lang/build/JavaClassRenameTest.java b/java/tests/integrationtests/com/google/idea/blaze/java/lang/build/JavaClassRenameTest.java
index 7a1a64d..04c83db 100644
--- a/java/tests/integrationtests/com/google/idea/blaze/java/lang/build/JavaClassRenameTest.java
+++ b/java/tests/integrationtests/com/google/idea/blaze/java/lang/build/JavaClassRenameTest.java
@@ -19,10 +19,15 @@
import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.refactoring.rename.RenameProcessor;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests that BUILD file references are correctly updated when performing rename refactors. */
+@RunWith(JUnit4.class)
public class JavaClassRenameTest extends BuildFileIntegrationTestCase {
+ @Test
public void testRenameJavaClass() {
PsiJavaFile javaFile =
(PsiJavaFile)
diff --git a/java/tests/integrationtests/com/google/idea/blaze/java/lang/build/SafeDeleteTest.java b/java/tests/integrationtests/com/google/idea/blaze/java/lang/build/SafeDeleteTest.java
index 535932a..bdee4a1 100644
--- a/java/tests/integrationtests/com/google/idea/blaze/java/lang/build/SafeDeleteTest.java
+++ b/java/tests/integrationtests/com/google/idea/blaze/java/lang/build/SafeDeleteTest.java
@@ -16,58 +16,61 @@
package com.google.idea.blaze.java.lang.build;
import com.google.idea.blaze.base.lang.buildfile.BuildFileIntegrationTestCase;
-import com.google.idea.blaze.base.lang.buildfile.psi.BuildFile;
import com.google.idea.blaze.base.lang.buildfile.psi.util.PsiUtils;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Tests for the safe delete action which aren't covered by existing tests. */
+@RunWith(JUnit4.class)
public class SafeDeleteTest extends BuildFileIntegrationTestCase {
+ @Test
public void testIndirectGlobReferencesNotIncluded() {
PsiFile javaFile =
createPsiFile("com/google/Test.java", "package com.google;", "public class Test {}");
PsiClass javaClass = PsiUtils.findFirstChildOfClassRecursive(javaFile, PsiClass.class);
- BuildFile buildFile =
- createBuildFile(
- "com/google/BUILD",
- "java_library(",
- " name = 'lib'",
- " srcs = glob(['*.java'])",
- ")");
+ createBuildFile(
+ "com/google/BUILD",
+ "java_library(",
+ " name = 'lib'",
+ " srcs = glob(['*.java'])",
+ ")");
try {
SafeDeleteHandler.invoke(getProject(), new PsiElement[] {javaClass}, true);
} catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
- fail("Glob reference was incorrectly included");
- return;
+ Assert.fail("Glob reference was incorrectly included");
}
}
+ @Test
public void testDirectGlobReferencesIncluded() {
PsiFile javaFile =
createPsiFile("com/google/Test.java", "package com.google;", "public class Test {}");
PsiClass javaClass = PsiUtils.findFirstChildOfClassRecursive(javaFile, PsiClass.class);
- BuildFile buildFile =
- createBuildFile(
- "com/google/BUILD",
- "java_library(",
- " name = 'lib'",
- " srcs = glob(['Test.java'])",
- ")");
+ createBuildFile(
+ "com/google/BUILD",
+ "java_library(",
+ " name = 'lib'",
+ " srcs = glob(['Test.java'])",
+ ")");
try {
SafeDeleteHandler.invoke(getProject(), new PsiElement[] {javaClass}, true);
} catch (BaseRefactoringProcessor.ConflictsInTestsException expected) {
return;
}
- fail("Expected an unsafe usage to be found");
+ Assert.fail("Expected an unsafe usage to be found");
}
}
diff --git a/java/tests/integrationtests/com/google/idea/blaze/java/sync/JavaSyncTest.java b/java/tests/integrationtests/com/google/idea/blaze/java/sync/JavaSyncTest.java
index 76dc9e1..717e398 100644
--- a/java/tests/integrationtests/com/google/idea/blaze/java/sync/JavaSyncTest.java
+++ b/java/tests/integrationtests/com/google/idea/blaze/java/sync/JavaSyncTest.java
@@ -19,9 +19,9 @@
import com.google.idea.blaze.base.ideinfo.JavaRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.ideinfo.RuleMapBuilder;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
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;
@@ -31,10 +31,15 @@
import com.google.idea.blaze.java.sync.model.BlazeJavaSyncData;
import com.google.idea.blaze.java.sync.model.BlazeSourceDirectory;
import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Java-specific sync integration tests. */
+@RunWith(JUnit4.class)
public class JavaSyncTest extends BlazeSyncIntegrationTestCase {
+ @Test
public void testJavaClassesPresentInClassPath() throws Exception {
setProjectView(
"directories:",
@@ -97,6 +102,7 @@
.isEqualTo(tempDirectory.getPath() + "/java/com/google");
}
+ @Test
public void testSimpleSync() throws Exception {
setProjectView(
"directories:",
diff --git a/java/tests/unittests/com/google/idea/blaze/java/run/BlazeJavaRunProfileStateTest.java b/java/tests/unittests/com/google/idea/blaze/java/run/BlazeJavaRunProfileStateTest.java
index b3dd584..51c2e6d 100644
--- a/java/tests/unittests/com/google/idea/blaze/java/run/BlazeJavaRunProfileStateTest.java
+++ b/java/tests/unittests/com/google/idea/blaze/java/run/BlazeJavaRunProfileStateTest.java
@@ -29,10 +29,10 @@
import com.google.idea.blaze.base.projectview.ProjectViewSet;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
-import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandler;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandGenericRunConfigurationHandlerProvider;
import com.google.idea.blaze.base.run.confighandler.BlazeCommandRunConfigurationHandlerProvider;
import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
+import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
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;
@@ -63,9 +63,6 @@
BlazeImportSettingsManager.class, new BlazeImportSettingsManager(project));
BlazeImportSettingsManager.getInstance(getProject()).setImportSettings(DUMMY_IMPORT_SETTINGS);
- configuration =
- new BlazeCommandRunConfigurationType().getFactory().createTemplateConfiguration(project);
-
ExperimentService experimentService = new MockExperimentService();
applicationServices.register(ExperimentService.class, experimentService);
applicationServices.register(RuleFinder.class, new MockRuleFinder());
@@ -76,15 +73,18 @@
BlazeCommandRunConfigurationHandlerProvider.EP_NAME,
BlazeCommandRunConfigurationHandlerProvider.class);
handlerProviderEp.registerExtension(new BlazeCommandGenericRunConfigurationHandlerProvider());
+
+ configuration =
+ new BlazeCommandRunConfigurationType().getFactory().createTemplateConfiguration(project);
}
@Test
public void flagsShouldBeAppendedIfPresent() {
configuration.setTarget(new Label("//label:rule"));
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) configuration.getHandler();
- handler.setCommand(BlazeCommandName.fromString("command"));
- handler.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
+ BlazeCommandRunConfigurationCommonState handlerState =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
+ handlerState.setCommand(BlazeCommandName.fromString("command"));
+ handlerState.setBlazeFlags(ImmutableList.of("--flag1", "--flag2"));
assertThat(
BlazeJavaRunProfileState.getBlazeCommand(
project, configuration, ProjectViewSet.builder().build(), false /* debug */)
@@ -103,9 +103,9 @@
@Test
public void debugFlagShouldBeIncludedForJavaTest() {
configuration.setTarget(new Label("//label:rule"));
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) configuration.getHandler();
- handler.setCommand(BlazeCommandName.fromString("command"));
+ BlazeCommandRunConfigurationCommonState handlerState =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
+ handlerState.setCommand(BlazeCommandName.fromString("command"));
assertThat(
BlazeJavaRunProfileState.getBlazeCommand(
project, configuration, ProjectViewSet.builder().build(), true /* debug */)
@@ -123,9 +123,9 @@
@Test
public void debugFlagShouldBeIncludedForJavaBinary() {
configuration.setTarget(new Label("//label:java_binary_rule"));
- BlazeCommandGenericRunConfigurationHandler handler =
- (BlazeCommandGenericRunConfigurationHandler) configuration.getHandler();
- handler.setCommand(BlazeCommandName.fromString("command"));
+ BlazeCommandRunConfigurationCommonState handlerState =
+ (BlazeCommandRunConfigurationCommonState) configuration.getHandler().getState();
+ handlerState.setCommand(BlazeCommandName.fromString("command"));
assertThat(
BlazeJavaRunProfileState.getBlazeCommand(
project, configuration, ProjectViewSet.builder().build(), true /* debug */)
diff --git a/java/tests/unittests/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporterTest.java b/java/tests/unittests/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporterTest.java
index 9b5aa31..c5461f1 100644
--- a/java/tests/unittests/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporterTest.java
+++ b/java/tests/unittests/com/google/idea/blaze/java/sync/importer/BlazeJavaWorkspaceImporterTest.java
@@ -34,9 +34,10 @@
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
import com.google.idea.blaze.base.ideinfo.ProtoLibraryLegacyInfo;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.ideinfo.RuleMapBuilder;
import com.google.idea.blaze.base.ideinfo.Tags;
-import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.LanguageClass;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
@@ -61,7 +62,6 @@
import com.google.idea.blaze.base.settings.BlazeImportSettingsManager;
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.java.sync.BlazeJavaSyncAugmenter;
import com.google.idea.blaze.java.sync.jdeps.JdepsMap;
@@ -98,33 +98,26 @@
private static final String FAKE_GEN_ROOT_EXECUTION_PATH_FRAGMENT =
"blaze-out/gcc-4.X.Y-crosstool-v17-hybrid-grtev3-k8-fastbuild/bin";
- private static final String FAKE_GEN_ROOT =
- "/path/to/8093958afcfde6c33d08b621dfaa4e09/root/" + FAKE_GEN_ROOT_EXECUTION_PATH_FRAGMENT;
private static final ArtifactLocationDecoder FAKE_ARTIFACT_DECODER =
- new ArtifactLocationDecoder(
- new BlazeRoots(
- new File("/"),
- ImmutableList.of(),
- new ExecutionRootPath("out/crosstool/bin"),
- new ExecutionRootPath("out/crosstool/gen")),
- null);
+ (ArtifactLocationDecoder)
+ artifactLocation -> new File("/", artifactLocation.getRelativePath());
private static final BlazeImportSettings DUMMY_IMPORT_SETTINGS =
new BlazeImportSettings("", "", "", "", "", BuildSystem.Blaze);
private ExtensionPointImpl<BlazeJavaSyncAugmenter> augmenters;
private static class JdepsMock implements JdepsMap {
- Map<Label, List<String>> jdeps = Maps.newHashMap();
+ Map<RuleKey, List<String>> jdeps = Maps.newHashMap();
@Nullable
@Override
- public List<String> getDependenciesForRule(@NotNull Label label) {
- return jdeps.get(label);
+ public List<String> getDependenciesForRule(RuleKey ruleKey) {
+ return jdeps.get(ruleKey);
}
- JdepsMock put(Label label, List<String> values) {
- jdeps.put(label, values);
+ JdepsMock put(RuleKey ruleKey, List<String> values) {
+ jdeps.put(ruleKey, values);
return this;
}
}
@@ -156,7 +149,9 @@
@Nullable
@Override
public String getDeclaredPackageOfJavaFile(
- @NotNull BlazeContext context, @NotNull SourceArtifact sourceArtifact) {
+ BlazeContext context,
+ ArtifactLocationDecoder artifactLocationDecoder,
+ SourceArtifact sourceArtifact) {
return null;
}
});
@@ -175,14 +170,17 @@
ProjectViewSet projectViewSet = ProjectViewSet.builder().add(projectView).build();
+ RuleMap ruleMap = ruleMapBuilder.build();
+ JavaSourceFilter sourceFilter =
+ new JavaSourceFilter(project, workspaceRoot, projectViewSet, ruleMap);
BlazeJavaWorkspaceImporter blazeWorkspaceImporter =
new BlazeJavaWorkspaceImporter(
project,
- context,
workspaceRoot,
projectViewSet,
workspaceLanguageSettings,
- ruleMapBuilder.build(),
+ ruleMap,
+ sourceFilter,
jdepsMap,
workingSet,
FAKE_ARTIFACT_DECODER);
@@ -235,9 +233,9 @@
errorCollector.assertNoIssues();
assertEquals(1, result.buildOutputJars.size());
- File compilerOutputLib = result.buildOutputJars.iterator().next();
+ ArtifactLocation compilerOutputLib = result.buildOutputJars.iterator().next();
assertNotNull(compilerOutputLib);
- assertTrue(compilerOutputLib.getPath().endsWith("example_debug.jar"));
+ assertTrue(compilerOutputLib.relativePath.endsWith("example_debug.jar"));
assertThat(result.contentEntries)
.containsExactly(
@@ -250,8 +248,8 @@
assertThat(result.javaSourceFiles)
.containsExactly(
- source("java/apps/example/MainActivity.java").getFile(),
- source("java/apps/example/subdir/SubdirHelper.java").getFile());
+ source("java/apps/example/MainActivity.java"),
+ source("java/apps/example/subdir/SubdirHelper.java"));
}
@Test
@@ -374,7 +372,7 @@
.build())
.build());
assertThat(result.javaSourceFiles)
- .containsExactly(source("java/apps/example/MainActivity.java").getFile());
+ .containsExactly(source("java/apps/example/MainActivity.java"));
}
/** Import a project and its tests */
@@ -992,7 +990,7 @@
.build();
RuleMapBuilder ruleMapBuilder = ruleMapForJdepsSuite();
jdepsMap.put(
- new Label("//java/apps/example:example_debug"),
+ RuleKey.forPlainTarget(new Label("//java/apps/example:example_debug")),
Lists.newArrayList(jdepsPath("thirdparty/a.jar"), jdepsPath("thirdparty/c.jar")));
BlazeJavaImportResult result = importWorkspace(workspaceRoot, ruleMapBuilder, projectView);
@@ -1220,7 +1218,7 @@
// First test - make sure that jdeps is working
jdepsMap.put(
- new Label("//java/example:liba"),
+ RuleKey.forPlainTarget(new Label("//java/example:liba")),
Lists.newArrayList(jdepsPath("thirdparty/proto/a/liba-ijar.jar")));
BlazeJavaImportResult result = importWorkspace(workspaceRoot, ruleMapBuilder, projectView);
errorCollector.assertNoIssues();
@@ -1338,7 +1336,7 @@
jars.add(
new BlazeJarLibrary(
LibraryArtifact.builder().setInterfaceJar(gen("source.jar")).build(),
- rule.label));
+ rule.key));
}
}
});
@@ -1382,19 +1380,14 @@
/* Utility methods */
private static String libraryFileName(BlazeJarLibrary library) {
- return library.libraryArtifact.jarForIntellijLibrary().getFile().getName();
+ return new File(library.libraryArtifact.jarForIntellijLibrary().relativePath).getName();
}
@Nullable
private static BlazeJarLibrary findLibrary(
Map<LibraryKey, BlazeJarLibrary> libraries, String libraryName) {
for (BlazeJarLibrary library : libraries.values()) {
- if (library
- .libraryArtifact
- .jarForIntellijLibrary()
- .getFile()
- .getPath()
- .endsWith(libraryName)) {
+ if (library.libraryArtifact.jarForIntellijLibrary().relativePath.endsWith(libraryName)) {
return library;
}
}
@@ -1403,7 +1396,6 @@
private ArtifactLocation source(String relativePath) {
return ArtifactLocation.builder()
- .setRootPath(FAKE_WORKSPACE_ROOT)
.setRelativePath(relativePath)
.setIsSource(true)
.build();
@@ -1411,7 +1403,6 @@
private static ArtifactLocation gen(String relativePath) {
return ArtifactLocation.builder()
- .setRootPath(FAKE_GEN_ROOT)
.setRootExecutionPathFragment(FAKE_GEN_ROOT_EXECUTION_PATH_FRAGMENT)
.setRelativePath(relativePath)
.setIsSource(false)
diff --git a/java/tests/unittests/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculatorTest.java b/java/tests/unittests/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculatorTest.java
index dec8f90..684cd7f 100644
--- a/java/tests/unittests/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculatorTest.java
+++ b/java/tests/unittests/com/google/idea/blaze/java/sync/source/SourceDirectoryCalculatorTest.java
@@ -20,12 +20,12 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.async.executor.MockBlazeExecutor;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.io.InputStreamProvider;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
@@ -40,6 +40,7 @@
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.sync.projectview.SourceTestConfig;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoderImpl;
import com.google.idea.blaze.base.sync.workspace.BlazeRoots;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverImpl;
import com.google.idea.blaze.java.sync.model.BlazeContentEntry;
@@ -66,7 +67,7 @@
@RunWith(JUnit4.class)
public class SourceDirectoryCalculatorTest extends BlazeTestCase {
- private static final ImmutableMap<Label, ArtifactLocation> NO_MANIFESTS = ImmutableMap.of();
+ private static final ImmutableMap<RuleKey, ArtifactLocation> NO_MANIFESTS = ImmutableMap.of();
private static final Label LABEL = new Label("//fake:label");
private MockInputStreamProvider mockInputStreamProvider;
@@ -78,13 +79,8 @@
private WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File("/root"));
private ArtifactLocationDecoder decoder =
- new ArtifactLocationDecoder(
- new BlazeRoots(
- new File("/"),
- Lists.newArrayList(new File("/usr/local/code")),
- new ExecutionRootPath("out/crosstool/bin"),
- new ExecutionRootPath("out/crosstool/gen")),
- null);
+ (ArtifactLocationDecoder)
+ artifactLocation -> new File("/root", artifactLocation.getRelativePath());
static final class TestSourceImportConfig extends SourceTestConfig {
final boolean isTest;
@@ -153,11 +149,10 @@
"/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -187,11 +182,10 @@
"/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -225,18 +219,16 @@
"package com.google.subpackage;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/subpackage/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -274,25 +266,22 @@
"package com.google.idea.blaze.plugin;\n public class Plugin {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/idea/blaze/plugin/run/Run.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/idea/blaze/plugin/sync/Sync.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/idea/blaze/plugin/Plugin.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -328,25 +317,22 @@
"package com.google.idea.blaze.incorrect;\n public class Incorrect {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/idea/blaze/plugin/run/Run.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/idea/blaze/plugin/sync/Sync.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/idea/blaze/Incorrect.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -386,18 +372,16 @@
"package com.google.different;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/subpackage/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -434,18 +418,16 @@
"package com.google.subpackage;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/subpackage/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -482,18 +464,16 @@
"package com.google.different;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/subpackage/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -527,11 +507,10 @@
"/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -561,11 +540,10 @@
"/root/java/com/google/Bla.java", "package com.facebook;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -595,11 +573,10 @@
"/root/java/com/org/foo/Bla.java", "package com.facebook;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/org/foo/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -633,23 +610,21 @@
"/root/java/com/facebook/Bla.java", "package com.facebook;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/facebook/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
- ImmutableList<BlazeContentEntry> result =
- sourceDirectoryCalculator.calculateContentEntries(
- project,
- context,
- workspaceRoot,
- new TestSourceImportConfig(false),
- decoder,
- ImmutableList.of(new WorkspacePath("java/com/google")),
- sourceArtifacts,
- NO_MANIFESTS);
+ sourceDirectoryCalculator.calculateContentEntries(
+ project,
+ context,
+ workspaceRoot,
+ new TestSourceImportConfig(false),
+ decoder,
+ ImmutableList.of(new WorkspacePath("java/com/google")),
+ sourceArtifacts,
+ NO_MANIFESTS);
issues.assertIssueContaining("Did not add");
}
@@ -661,23 +636,21 @@
"/root/java/com/facebook/Bla.java", "package com.facebook;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/facebook/Bla.java")
- .setRootPath("/root")
.setIsSource(false))
.build());
- ImmutableList<BlazeContentEntry> result =
- sourceDirectoryCalculator.calculateContentEntries(
- project,
- context,
- workspaceRoot,
- new TestSourceImportConfig(false),
- decoder,
- ImmutableList.of(new WorkspacePath("java/com/google/my")),
- sourceArtifacts,
- NO_MANIFESTS);
+ sourceDirectoryCalculator.calculateContentEntries(
+ project,
+ context,
+ workspaceRoot,
+ new TestSourceImportConfig(false),
+ decoder,
+ ImmutableList.of(new WorkspacePath("java/com/google/my")),
+ sourceArtifacts,
+ NO_MANIFESTS);
issues.assertNoIssues();
}
@@ -686,23 +659,21 @@
mockInputStreamProvider.addFile("/root/java/com/google/Bla.java", "public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
- ImmutableList<BlazeContentEntry> result =
- sourceDirectoryCalculator.calculateContentEntries(
- project,
- context,
- workspaceRoot,
- new TestSourceImportConfig(false),
- decoder,
- ImmutableList.of(new WorkspacePath("java/com/google")),
- sourceArtifacts,
- NO_MANIFESTS);
+ sourceDirectoryCalculator.calculateContentEntries(
+ project,
+ context,
+ workspaceRoot,
+ new TestSourceImportConfig(false),
+ decoder,
+ ImmutableList.of(new WorkspacePath("java/com/google")),
+ sourceArtifacts,
+ NO_MANIFESTS);
issues.assertIssueContaining("No package name string found");
}
@@ -717,32 +688,28 @@
.addFile("/root/java/com/google/Bla3.java", "package com.google;\n public class Bla3 {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla2.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla3.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Foo.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -779,25 +746,22 @@
"package com.google.subpackage.subsubpackage;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/subpackage/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/subpackage/subsubpackage/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -836,18 +800,16 @@
"package com.google.packagewrong1;\n public class Bla {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/package0/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/package1/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -891,20 +853,18 @@
"package com.google.android.chimera.container;\n public class FileApkUtils {}");
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath(
"java/com/google/android/chimera/internal/Preconditions.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath(
"java/com/google/android/chimera/container/FileApkUtils.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
ImmutableList<BlazeContentEntry> result =
@@ -942,21 +902,25 @@
.setIsSource(true)
.build()),
ImmutableList.of("com.google"));
- ImmutableMap<Label, ArtifactLocation> manifests =
- ImmutableMap.<Label, ArtifactLocation>builder()
+ ImmutableMap<RuleKey, ArtifactLocation> manifests =
+ ImmutableMap.<RuleKey, ArtifactLocation>builder()
.put(
- LABEL,
+ RuleKey.forPlainTarget(LABEL),
ArtifactLocation.builder()
.setRelativePath("java/com/test.manifest")
- .setRootPath("/root")
.setIsSource(true)
.build())
.build();
- Map<Label, Map<String, String>> manifestMap =
+ Map<RuleKey, Map<ArtifactLocation, String>> manifestMap =
readPackageManifestFiles(manifests, getDecoder("/root"));
- assertThat(manifestMap.get(LABEL))
- .containsEntry("/root/java/com/google/Bla.java", "com.google");
+ assertThat(manifestMap.get(RuleKey.forPlainTarget(LABEL)))
+ .containsEntry(
+ ArtifactLocation.builder()
+ .setRelativePath("java/com/google/Bla.java")
+ .setIsSource(true)
+ .build(),
+ "com.google");
}
@Test
@@ -965,21 +929,25 @@
"/root/java/com/test.manifest",
ImmutableList.of("java/com/google/Bla.java"),
ImmutableList.of("com.google"));
- ImmutableMap<Label, ArtifactLocation> manifests =
- ImmutableMap.<Label, ArtifactLocation>builder()
+ ImmutableMap<RuleKey, ArtifactLocation> manifests =
+ ImmutableMap.<RuleKey, ArtifactLocation>builder()
.put(
- LABEL,
+ RuleKey.forPlainTarget(LABEL),
ArtifactLocation.builder()
.setRelativePath("java/com/test.manifest")
- .setRootPath("/root")
.setIsSource(true)
.build())
.build();
- Map<Label, Map<String, String>> manifestMap =
+ Map<RuleKey, Map<ArtifactLocation, String>> manifestMap =
readPackageManifestFiles(manifests, getDecoder("/root"));
- assertThat(manifestMap.get(LABEL))
- .containsEntry("/root/java/com/google/Bla.java", "com.google");
+ assertThat(manifestMap.get(RuleKey.forPlainTarget(LABEL)))
+ .containsEntry(
+ ArtifactLocation.builder()
+ .setRelativePath("java/com/google/Bla.java")
+ .setIsSource(true)
+ .build(),
+ "com.google");
}
@Test
@@ -992,34 +960,47 @@
"/root/java/com/test2.manifest",
ImmutableList.of("java/com/google/Bla.java", "java/com/google/other/Temp.java"),
ImmutableList.of("com.google", "com.google.other"));
- ImmutableMap<Label, ArtifactLocation> manifests =
- ImmutableMap.<Label, ArtifactLocation>builder()
+ ImmutableMap<RuleKey, ArtifactLocation> manifests =
+ ImmutableMap.<RuleKey, ArtifactLocation>builder()
.put(
- new Label("//a:a"),
+ RuleKey.forPlainTarget(new Label("//a:a")),
ArtifactLocation.builder()
.setRelativePath("java/com/test.manifest")
- .setRootPath("/root")
.setIsSource(true)
.build())
.put(
- new Label("//b:b"),
+ RuleKey.forPlainTarget(new Label("//b:b")),
ArtifactLocation.builder()
.setRelativePath("java/com/test2.manifest")
- .setRootPath("/root")
.setIsSource(true)
.build())
.build();
- Map<Label, Map<String, String>> manifestMap =
+ Map<RuleKey, Map<ArtifactLocation, String>> manifestMap =
readPackageManifestFiles(manifests, getDecoder("/root"));
assertThat(manifestMap).hasSize(2);
- assertThat(manifestMap.get(new Label("//a:a")))
- .containsEntry("/root/java/com/google/Bla.java", "com.google");
- assertThat(manifestMap.get(new Label("//a:a")))
- .containsEntry("/root/java/com/google/Foo.java", "com.google.subpackage");
- assertThat(manifestMap.get(new Label("//b:b")))
- .containsEntry("/root/java/com/google/other/Temp.java", "com.google.other");
+ assertThat(manifestMap.get(RuleKey.forPlainTarget(new Label("//a:a"))))
+ .containsEntry(
+ ArtifactLocation.builder()
+ .setRelativePath("java/com/google/Bla.java")
+ .setIsSource(true)
+ .build(),
+ "com.google");
+ assertThat(manifestMap.get(RuleKey.forPlainTarget(new Label("//a:a"))))
+ .containsEntry(
+ ArtifactLocation.builder()
+ .setRelativePath("java/com/google/Foo.java")
+ .setIsSource(true)
+ .build(),
+ "com.google.subpackage");
+ assertThat(manifestMap.get(RuleKey.forPlainTarget(new Label("//b:b"))))
+ .containsEntry(
+ ArtifactLocation.builder()
+ .setRelativePath("java/com/google/other/Temp.java")
+ .setIsSource(true)
+ .build(),
+ "com.google.other");
}
@Test
@@ -1033,38 +1014,34 @@
"/root/java/com/google/subpackage/Bla.java",
"package com.google.different;\n public class Bla {}");
- ImmutableMap<Label, ArtifactLocation> manifests =
- ImmutableMap.<Label, ArtifactLocation>builder()
+ ImmutableMap<RuleKey, ArtifactLocation> manifests =
+ ImmutableMap.<RuleKey, ArtifactLocation>builder()
.put(
- LABEL,
+ RuleKey.forPlainTarget(LABEL),
ArtifactLocation.builder()
.setRelativePath("java/com/test.manifest")
- .setRootPath("/root")
.setIsSource(true)
.build())
.build();
List<SourceArtifact> sourceArtifacts =
ImmutableList.of(
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/Foo.java")
- .setRootPath("/root")
.setIsSource(true))
.build(),
- SourceArtifact.builder(LABEL)
+ SourceArtifact.builder(RuleKey.forPlainTarget(LABEL))
.setArtifactLocation(
ArtifactLocation.builder()
.setRelativePath("java/com/google/subpackage/Bla.java")
- .setRootPath("/root")
.setIsSource(true))
.build());
@@ -1095,9 +1072,7 @@
}
private void setPackageManifest(
- String manifestPath,
- List<String> sourceRelativePaths,
- List<String> packages) {
+ String manifestPath, List<String> sourceRelativePaths, List<String> packages) {
PackageManifest.Builder manifest = PackageManifest.newBuilder();
for (int i = 0; i < sourceRelativePaths.size(); i++) {
String sourceRelativePath = sourceRelativePaths.get(i);
@@ -1137,7 +1112,8 @@
ImmutableList.of(root),
new ExecutionRootPath("out/crosstool/bin"),
new ExecutionRootPath("out/crosstool/gen"));
- return new ArtifactLocationDecoder(roots, new WorkspacePathResolverImpl(workspaceRoot, roots));
+ return new ArtifactLocationDecoderImpl(
+ roots, new WorkspacePathResolverImpl(workspaceRoot, roots));
}
private static class MockInputStreamProvider implements InputStreamProvider {
@@ -1169,8 +1145,8 @@
}
}
- private Map<Label, Map<String, String>> readPackageManifestFiles(
- Map<Label, ArtifactLocation> manifests, ArtifactLocationDecoder decoder) {
+ private Map<RuleKey, Map<ArtifactLocation, String>> readPackageManifestFiles(
+ Map<RuleKey, ArtifactLocation> manifests, ArtifactLocationDecoder decoder) {
return PackageManifestReader.getInstance()
.readPackageManifestFiles(
project, context, decoder, manifests, MoreExecutors.sameThreadExecutor());
diff --git a/plugin_dev/BUILD b/plugin_dev/BUILD
index 0e90f5a..48eb552 100644
--- a/plugin_dev/BUILD
+++ b/plugin_dev/BUILD
@@ -55,7 +55,7 @@
)
load(
- "//intellij_test:test_defs.bzl",
+ "//testing:test_defs.bzl",
"intellij_integration_test_suite",
)
@@ -74,5 +74,6 @@
"//base:unit_test_utils",
"//intellij_platform_sdk:plugin_api_for_tests",
"@jsr305_annotations//jar",
+ "@junit//jar",
],
)
diff --git a/plugin_dev/src/META-INF/blaze-plugin-dev.xml b/plugin_dev/src/META-INF/blaze-plugin-dev.xml
index 8725148..af9bc68 100644
--- a/plugin_dev/src/META-INF/blaze-plugin-dev.xml
+++ b/plugin_dev/src/META-INF/blaze-plugin-dev.xml
@@ -17,7 +17,7 @@
<depends>DevKit</depends>
<extensions defaultExtensionNs="com.google.idea.blaze">
- <RuleConfigurationFactory implementation="com.google.idea.blaze.plugin.run.BlazeIntellijPluginConfigurationType$BlazeIntellijPluginRuleConfigurationFactory"/>
+ <RunConfigurationFactory implementation="com.google.idea.blaze.plugin.run.BlazeIntellijPluginConfigurationType$BlazeIntellijPluginRunConfigurationFactory"/>
<SyncPlugin implementation="com.google.idea.blaze.plugin.sync.IntellijPluginSyncPlugin"/>
</extensions>
diff --git a/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfiguration.java b/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfiguration.java
index d909032..57e0e9c 100644
--- a/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfiguration.java
+++ b/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfiguration.java
@@ -27,6 +27,7 @@
import com.google.idea.blaze.base.ideinfo.JavaRuleIdeInfo;
import com.google.idea.blaze.base.ideinfo.LibraryArtifact;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+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.TargetExpression;
import com.google.idea.blaze.base.projectview.ProjectViewSet;
@@ -34,6 +35,8 @@
import com.google.idea.blaze.base.run.BlazeRunConfiguration;
import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
import com.google.idea.blaze.base.settings.Blaze;
+import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
+import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.base.ui.UiUtil;
import com.google.idea.blaze.plugin.IntellijPluginRule;
import com.intellij.execution.ExecutionException;
@@ -136,29 +139,42 @@
this.target = target;
}
+ public void setPluginSdk(Sdk sdk) {
+ if (IdeaJdkHelper.isIdeaJdk(sdk)) {
+ pluginSdk = sdk;
+ }
+ }
+
private ImmutableList<File> findPluginJars() throws ExecutionException {
+ BlazeProjectData blazeProjectData =
+ BlazeProjectDataManager.getInstance(getProject()).getBlazeProjectData();
+ if (blazeProjectData == null) {
+ throw new ExecutionException("Not synced yet, please sync project");
+ }
RuleIdeInfo rule = RuleFinder.getInstance().ruleForTarget(getProject(), getTarget());
if (rule == null) {
throw new ExecutionException(
buildSystem + " rule '" + getTarget() + "' not imported during sync");
}
return IntellijPluginRule.isPluginBundle(rule)
- ? findBundledJars(rule)
- : ImmutableList.of(findPluginJar(rule));
+ ? findBundledJars(blazeProjectData.artifactLocationDecoder, rule)
+ : ImmutableList.of(findPluginJar(blazeProjectData.artifactLocationDecoder, rule));
}
- private ImmutableList<File> findBundledJars(RuleIdeInfo rule) throws ExecutionException {
+ private ImmutableList<File> findBundledJars(
+ ArtifactLocationDecoder artifactLocationDecoder, RuleIdeInfo rule) throws ExecutionException {
ImmutableList.Builder<File> jars = ImmutableList.builder();
for (Label dep : rule.dependencies) {
RuleIdeInfo depRule = RuleFinder.getInstance().ruleForTarget(getProject(), dep);
if (depRule != null && IntellijPluginRule.isSinglePluginRule(depRule)) {
- jars.add(findPluginJar(depRule));
+ jars.add(findPluginJar(artifactLocationDecoder, depRule));
}
}
return jars.build();
}
- private File findPluginJar(RuleIdeInfo rule) throws ExecutionException {
+ private File findPluginJar(ArtifactLocationDecoder artifactLocationDecoder, RuleIdeInfo rule)
+ throws ExecutionException {
JavaRuleIdeInfo javaRuleIdeInfo = rule.javaRuleIdeInfo;
if (!IntellijPluginRule.isSinglePluginRule(rule) || javaRuleIdeInfo == null) {
throw new ExecutionException(
@@ -172,7 +188,7 @@
if (artifact == null || artifact.classJar == null) {
throw new ExecutionException("No output plugin jar found for '" + rule.label + "'");
}
- return artifact.classJar.getFile();
+ return artifactLocationDecoder.decode(artifact.classJar);
}
/**
diff --git a/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfigurationType.java b/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfigurationType.java
index 38baa96..5ff8d45 100644
--- a/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfigurationType.java
+++ b/plugin_dev/src/com/google/idea/blaze/plugin/run/BlazeIntellijPluginConfigurationType.java
@@ -16,11 +16,13 @@
package com.google.idea.blaze.plugin.run;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleKey;
+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.WorkspaceType;
-import com.google.idea.blaze.base.run.BlazeRuleConfigurationFactory;
+import com.google.idea.blaze.base.run.BlazeRunConfigurationFactory;
import com.google.idea.blaze.base.run.rulefinder.RuleFinder;
import com.google.idea.blaze.base.settings.Blaze;
-import com.google.idea.blaze.base.sync.projectview.WorkspaceLanguageSettings;
import com.google.idea.blaze.plugin.IntellijPluginRule;
import com.intellij.diagnostic.VMOptions;
import com.intellij.execution.BeforeRunTask;
@@ -30,6 +32,8 @@
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NullableLazyValue;
import javax.annotation.Nullable;
@@ -44,12 +48,15 @@
private final BlazeIntellijPluginConfigurationFactory factory =
new BlazeIntellijPluginConfigurationFactory(this);
- static class BlazeIntellijPluginRuleConfigurationFactory extends BlazeRuleConfigurationFactory {
+ static class BlazeIntellijPluginRunConfigurationFactory extends BlazeRunConfigurationFactory {
@Override
- public boolean handlesRule(
- WorkspaceLanguageSettings workspaceLanguageSettings, RuleIdeInfo rule) {
- return workspaceLanguageSettings.isWorkspaceType(WorkspaceType.INTELLIJ_PLUGIN)
- && IntellijPluginRule.isPluginRule(rule);
+ public boolean handlesTarget(Project project, BlazeProjectData blazeProjectData, Label target) {
+ if (!blazeProjectData.workspaceLanguageSettings.isWorkspaceType(
+ WorkspaceType.INTELLIJ_PLUGIN)) {
+ return false;
+ }
+ RuleIdeInfo rule = blazeProjectData.ruleMap.get(RuleKey.forPlainTarget(target));
+ return rule != null && IntellijPluginRule.isPluginRule(rule);
}
@Override
@@ -58,10 +65,10 @@
}
@Override
- public void setupConfiguration(RunConfiguration configuration, RuleIdeInfo rule) {
+ public void setupConfiguration(RunConfiguration configuration, Label target) {
final BlazeIntellijPluginConfiguration pluginConfig =
(BlazeIntellijPluginConfiguration) configuration;
- getInstance().factory.setupConfigurationForRule(pluginConfig, rule);
+ getInstance().factory.setupConfigurationForRule(pluginConfig, target);
}
}
@@ -103,13 +110,16 @@
task.setEnabled(providerID.equals(BuildPluginBeforeRunTaskProvider.ID));
}
- void setupConfigurationForRule(
- BlazeIntellijPluginConfiguration configuration, RuleIdeInfo rule) {
- configuration.setTarget(rule.label);
+ void setupConfigurationForRule(BlazeIntellijPluginConfiguration configuration, Label target) {
+ configuration.setTarget(target);
configuration.setGeneratedName();
if (configuration.vmParameters == null) {
configuration.vmParameters = currentVmOptions.getValue();
}
+ Sdk projectSdk = ProjectRootManager.getInstance(configuration.getProject()).getProjectSdk();
+ if (IdeaJdkHelper.isIdeaJdk(projectSdk)) {
+ configuration.setPluginSdk(projectSdk);
+ }
}
@Override
diff --git a/plugin_dev/tests/integrationtests/com/google/idea/blaze/plugin/sync/PluginDevSyncTest.java b/plugin_dev/tests/integrationtests/com/google/idea/blaze/plugin/sync/PluginDevSyncTest.java
index 492a6fb..9515601 100644
--- a/plugin_dev/tests/integrationtests/com/google/idea/blaze/plugin/sync/PluginDevSyncTest.java
+++ b/plugin_dev/tests/integrationtests/com/google/idea/blaze/plugin/sync/PluginDevSyncTest.java
@@ -18,9 +18,9 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.idea.blaze.base.ideinfo.RuleIdeInfo;
+import com.google.idea.blaze.base.ideinfo.RuleMap;
import com.google.idea.blaze.base.ideinfo.RuleMapBuilder;
import com.google.idea.blaze.base.model.BlazeProjectData;
-import com.google.idea.blaze.base.model.RuleMap;
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;
@@ -30,10 +30,15 @@
import com.intellij.execution.RunManager;
import com.intellij.execution.configurations.RunConfiguration;
import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
/** Plugin-dev specific sync integration test. */
+@RunWith(JUnit4.class)
public class PluginDevSyncTest extends BlazeSyncIntegrationTestCase {
+ @Test
public void testRunConfigurationCreatedDuringSync() throws Exception {
setProjectView(
"directories:",
diff --git a/proto_deps/proto_deps.jar b/proto_deps/proto_deps.jar
index 80b6046..25a6ec4 100755
--- a/proto_deps/proto_deps.jar
+++ b/proto_deps/proto_deps.jar
Binary files differ
diff --git a/intellij_test/BUILD b/testing/BUILD
similarity index 100%
rename from intellij_test/BUILD
rename to testing/BUILD
diff --git a/intellij_test/src/com/google/idea/blaze/base/BlazeTestSystemProperties.java b/testing/src/com/google/idea/testing/BlazeTestSystemPropertiesRule.java
similarity index 75%
rename from intellij_test/src/com/google/idea/blaze/base/BlazeTestSystemProperties.java
rename to testing/src/com/google/idea/testing/BlazeTestSystemPropertiesRule.java
index c8a3351..f8d7f19 100644
--- a/intellij_test/src/com/google/idea/blaze/base/BlazeTestSystemProperties.java
+++ b/testing/src/com/google/idea/testing/BlazeTestSystemPropertiesRule.java
@@ -13,10 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.google.idea.blaze.base;
+package com.google.idea.testing;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
+import com.google.common.io.Files;
+import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
@@ -24,25 +26,28 @@
import java.io.File;
import java.io.IOException;
import java.net.URL;
+import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.List;
import javax.annotation.Nullable;
+import org.junit.rules.ExternalResource;
-/** Test utilities specific to running in a blaze/bazel environment. */
-public class BlazeTestSystemProperties {
+/**
+ * Test utilities specific to running IntelliJ integration tests in a blaze/bazel environment.
+ * Should be instantiated as a @ClassRule in the outermost test class/suite.
+ */
+public class BlazeTestSystemPropertiesRule extends ExternalResource {
+
+ @Override
+ protected void before() throws Throwable {
+ configureSystemProperties();
+ }
/** The absolute path to the runfiles directory. */
private static final String RUNFILES_PATH = getUserValue("TEST_SRCDIR");
- public static boolean isRunThroughBlaze() {
- return System.getenv("JAVA_RUNFILES") != null;
- }
-
/** Sets up the necessary system properties for running IntelliJ tests via blaze/bazel. */
- public static void configureSystemProperties() throws IOException {
- if (!isRunThroughBlaze()) {
- return;
- }
+ private static void configureSystemProperties() throws IOException {
File sandbox = new File(getTmpDirFile(), "_intellij_test_sandbox");
setSandboxPath("idea.home.path", new File(sandbox, "home"));
@@ -51,6 +56,10 @@
setIfEmpty(PlatformUtils.PLATFORM_PREFIX_KEY, "Idea");
setIfEmpty("idea.classpath.index.enabled", "false");
+ // Some plugins have a since-build and until-build restriction, so we need
+ // to update the build number here
+ PluginManagerCore.BUILD_NUMBER = readApiVersionNumber();
+
// Tests fail if they access files outside of the project roots and other system directories.
// Ensure runfiles and platform api are whitelisted.
VfsRootAccess.allowRootAccess(RUNFILES_PATH);
@@ -62,7 +71,7 @@
List<String> pluginJars = Lists.newArrayList();
try {
Enumeration<URL> urls =
- BlazeTestSystemProperties.class.getClassLoader().getResources("META-INF/plugin.xml");
+ BlazeTestSystemPropertiesRule.class.getClassLoader().getResources("META-INF/plugin.xml");
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
addArchiveFile(url, pluginJars);
@@ -75,6 +84,26 @@
setIfEmpty("idea.plugins.path", Joiner.on(File.pathSeparator).join(pluginJars));
}
+ private static String readApiVersionNumber() {
+ String apiVersionFilePath = System.getProperty("blaze.idea.api.version.file");
+ String runfilesWorkspaceRoot = System.getProperty("user.dir");
+ if (apiVersionFilePath == null) {
+ throw new RuntimeException("No api_version_file found in runfiles directory");
+ }
+ if (runfilesWorkspaceRoot == null) {
+ throw new RuntimeException("Runfiles workspace root not found");
+ }
+ File apiVersionFile = new File(runfilesWorkspaceRoot, apiVersionFilePath);
+ if (!apiVersionFile.canRead()) {
+ return null;
+ }
+ try {
+ return Files.readFirstLine(apiVersionFile, StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
@Nullable
private static String getPlatformApiPath() {
String platformJar = PathManager.getJarPathForClass(Application.class);
diff --git a/testing/src/com/google/idea/testing/EdtRule.java b/testing/src/com/google/idea/testing/EdtRule.java
new file mode 100644
index 0000000..4f374d2
--- /dev/null
+++ b/testing/src/com/google/idea/testing/EdtRule.java
@@ -0,0 +1,38 @@
+/*
+ * 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.testing;
+
+import com.intellij.testFramework.EdtTestUtil;
+import com.intellij.testFramework.TestRunnerUtil;
+import com.intellij.util.ThrowableRunnable;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/** Rule to run tests on the EDT. */
+public class EdtRule implements TestRule {
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ TestRunnerUtil.replaceIdeEventQueueSafely();
+ EdtTestUtil.runInEdtAndWait((ThrowableRunnable<Throwable>) base::evaluate);
+ }
+ };
+ }
+}
diff --git a/testing/src/com/google/idea/testing/IntellijTestSetupRule.java b/testing/src/com/google/idea/testing/IntellijTestSetupRule.java
new file mode 100644
index 0000000..4f9252c
--- /dev/null
+++ b/testing/src/com/google/idea/testing/IntellijTestSetupRule.java
@@ -0,0 +1,130 @@
+/*
+ * 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.testing;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.io.FileSystemUtil;
+import com.intellij.util.ReflectionUtil;
+import com.intellij.util.ui.UIUtil;
+import java.io.File;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.junit.rules.ExternalResource;
+
+/**
+ * Runs before and after each test, performing the checks in {@link
+ * com.intellij.testFramework.UsefulTestCase}
+ */
+public class IntellijTestSetupRule extends ExternalResource {
+
+ private static final Set<?> DELETE_ON_EXIT_HOOK_DOT_FILES;
+ private static final Class<?> DELETE_ON_EXIT_HOOK_CLASS;
+
+ static {
+ // Radar #5755208: Command line Java applications need a way to launch without a Dock icon.
+ System.setProperty("apple.awt.UIElement", "true");
+
+ try {
+ Class<?> aClass = Class.forName("java.io.DeleteOnExitHook");
+ Set<?> files = ReflectionUtil.getStaticFieldValue(aClass, Set.class, "files");
+ DELETE_ON_EXIT_HOOK_CLASS = aClass;
+ DELETE_ON_EXIT_HOOK_DOT_FILES = files;
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Disposable testRootDisposable;
+
+ private String oldPluginPathProperty;
+
+ @Override
+ protected void before() throws Throwable {
+ if (!isRunThroughBlaze()) {
+ // If running directly through the IDE, don't try to load plugins from the sandbox environment
+ // Instead we'll rely on the slightly more hermetic module classpath
+ oldPluginPathProperty = System.getProperty(PathManager.PROPERTY_PLUGINS_PATH);
+ System.setProperty(PathManager.PROPERTY_PLUGINS_PATH, "/dev/null");
+ }
+ testRootDisposable = Disposer.newDisposable();
+ }
+
+ @Override
+ protected void after() {
+ if (oldPluginPathProperty != null) {
+ System.setProperty(PathManager.PROPERTY_PLUGINS_PATH, oldPluginPathProperty);
+ } else {
+ System.clearProperty(PathManager.PROPERTY_PLUGINS_PATH);
+ }
+ try {
+ Disposer.dispose(testRootDisposable);
+ cleanupSwingDataStructures();
+ cleanupDeleteOnExitHookList();
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+
+ UIUtil.removeLeakingAppleListeners();
+ }
+
+ private static boolean isRunThroughBlaze() {
+ return System.getenv("JAVA_RUNFILES") != null;
+ }
+
+ private static void cleanupSwingDataStructures() throws Exception {
+ Object manager =
+ ReflectionUtil.getDeclaredMethod(
+ Class.forName("javax.swing.KeyboardManager"), "getCurrentManager")
+ .invoke(null);
+ Map<?, ?> componentKeyStrokeMap =
+ ReflectionUtil.getField(
+ manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
+ componentKeyStrokeMap.clear();
+ Map<?, ?> containerMap =
+ ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
+ containerMap.clear();
+ }
+
+ private static void cleanupDeleteOnExitHookList() throws Exception {
+ // try to reduce file set retained by java.io.DeleteOnExitHook
+ List<String> list;
+ synchronized (DELETE_ON_EXIT_HOOK_CLASS) {
+ if (DELETE_ON_EXIT_HOOK_DOT_FILES.isEmpty()) {
+ return;
+ }
+ list =
+ DELETE_ON_EXIT_HOOK_DOT_FILES
+ .stream()
+ .filter(p -> p instanceof String)
+ .map(p -> (String) p)
+ .collect(Collectors.toList());
+ }
+ for (int i = list.size() - 1; i >= 0; i--) {
+ String path = list.get(i);
+ if (FileSystemUtil.getAttributes(path) == null || new File(path).delete()) {
+ synchronized (DELETE_ON_EXIT_HOOK_CLASS) {
+ DELETE_ON_EXIT_HOOK_DOT_FILES.remove(path);
+ }
+ }
+ }
+ }
+}
diff --git a/testing/src/com/google/idea/testing/ServiceHelper.java b/testing/src/com/google/idea/testing/ServiceHelper.java
new file mode 100644
index 0000000..6b76692
--- /dev/null
+++ b/testing/src/com/google/idea/testing/ServiceHelper.java
@@ -0,0 +1,66 @@
+/*
+ * 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.testing;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.extensions.ExtensionPoint;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import org.picocontainer.MutablePicoContainer;
+
+/** Utility class for registering project services, application services and extensions. */
+public class ServiceHelper {
+
+ public static <T> void registerExtension(
+ ExtensionPointName<T> name, T instance, Disposable parentDisposable) {
+ ExtensionPoint<T> ep = Extensions.getRootArea().getExtensionPoint(name);
+ ep.registerExtension(instance);
+ Disposer.register(parentDisposable, () -> ep.unregisterExtension(instance));
+ }
+
+ public static <T> void registerApplicationService(
+ Class<T> key, T implementation, Disposable parentDisposable) {
+ registerComponentInstance(
+ (MutablePicoContainer) ApplicationManager.getApplication().getPicoContainer(),
+ key,
+ implementation,
+ parentDisposable);
+ }
+
+ public static <T> void registerProjectService(
+ Project project, Class<T> key, T implementation, Disposable parentDisposable) {
+ registerComponentInstance(
+ (MutablePicoContainer) project.getPicoContainer(), key, implementation, parentDisposable);
+ }
+
+ private static <T> void registerComponentInstance(
+ MutablePicoContainer container, Class<T> key, T implementation, Disposable parentDisposable) {
+ Object old = container.getComponentInstance(key);
+ container.unregisterComponent(key.getName());
+ container.registerComponentInstance(key.getName(), implementation);
+ Disposer.register(
+ parentDisposable,
+ () -> {
+ container.unregisterComponent(key.getName());
+ if (old != null) {
+ container.registerComponentInstance(key.getName(), old);
+ }
+ });
+ }
+}
diff --git a/testing/test_defs.bzl b/testing/test_defs.bzl
new file mode 100644
index 0000000..38baa7c
--- /dev/null
+++ b/testing/test_defs.bzl
@@ -0,0 +1,166 @@
+"""Custom rule for creating IntelliJ plugin tests.
+"""
+
+load(
+ "//build_defs:build_defs.bzl",
+ "api_version_txt",
+)
+
+def intellij_unit_test_suite(name, srcs, test_package_root, **kwargs):
+ """Creates a java_test rule comprising all valid test classes in the specified srcs.
+
+ Only classes ending in "Test.java" will be recognized.
+
+ Args:
+ name: name of this rule.
+ srcs: the test classes.
+ test_package_root: only tests under this package root will be run.
+ **kwargs: Any other args to be passed to the java_test.
+ """
+ test_srcs = [test for test in srcs if test.endswith("Test.java")]
+ test_classes = [_get_test_class(test_src, test_package_root) for test_src in test_srcs]
+ suite_class_name = name + "TestSuite"
+ suite_class = test_package_root + "." + suite_class_name
+ _generate_test_suite(
+ name = suite_class_name,
+ test_package_root = test_package_root,
+ test_classes = test_classes,
+ )
+ native.java_test(
+ name = name,
+ srcs = srcs + [suite_class_name],
+ test_class = suite_class,
+ **kwargs)
+
+def intellij_integration_test_suite(
+ name,
+ srcs,
+ test_package_root,
+ deps,
+ jvm_flags = [],
+ runtime_deps = [],
+ platform_prefix="Idea",
+ required_plugins=None,
+ **kwargs):
+ """Creates a java_test rule comprising all valid test classes in the specified srcs.
+
+ Only classes ending in "Test.java" will be recognized.
+
+ All test classes must be located in the blaze package calling this function.
+
+ Args:
+ name: name of this rule.
+ srcs: the test classes.
+ test_package_root: only tests under this package root will be run.
+ deps: the required deps.
+ jvm_flags: extra flags to be passed to the test vm.
+ runtime_deps: the required runtime_deps.
+ platform_prefix: Specifies the JetBrains product these tests are run against. Examples are
+ 'Idea' (IJ CE), 'idea' (IJ UE), 'CLion', 'AndroidStudio'. See
+ com.intellij.util.PlatformUtils for other options.
+ required_plugins: optional comma-separated list of plugin IDs. Integration tests will fail if
+ these plugins aren't loaded at runtime.
+ **kwargs: Any other args to be passed to the java_test.
+ """
+ test_srcs = [test for test in srcs if test.endswith("Test.java")]
+ test_classes = [_get_test_class(test_src, test_package_root) for test_src in test_srcs]
+ suite_class_name = name + "TestSuite"
+ suite_class = test_package_root + "." + suite_class_name
+ _generate_test_suite(
+ name = suite_class_name,
+ test_package_root = test_package_root,
+ test_classes = test_classes,
+ class_rules = ["com.google.idea.testing.BlazeTestSystemPropertiesRule"]
+ )
+
+ api_version_txt_name = name + "_api_version"
+ api_version_txt(name = api_version_txt_name)
+ data = kwargs.pop("data", [])
+ data.append(api_version_txt_name)
+
+ deps = list(deps)
+ deps.extend([
+ "//testing:lib",
+ ])
+ runtime_deps = list(runtime_deps)
+ runtime_deps.extend([
+ "//intellij_platform_sdk:bundled_plugins",
+ "//third_party:jdk8_tools",
+ ])
+
+ jvm_flags = list(jvm_flags)
+ jvm_flags.extend([
+ "-Didea.classpath.index.enabled=false",
+ "-Djava.awt.headless=true",
+ "-Didea.platform.prefix=" + platform_prefix,
+ "-Dblaze.idea.api.version.file=$(location %s)" % api_version_txt_name
+ ])
+
+ if required_plugins:
+ jvm_flags.append("-Didea.required.plugins.id=" + required_plugins)
+
+ native.java_test(
+ name = name,
+ size = "medium",
+ srcs = srcs + [suite_class_name],
+ data = data,
+ jvm_flags = jvm_flags,
+ test_class = suite_class,
+ runtime_deps = runtime_deps,
+ deps = deps,
+ **kwargs
+ )
+
+def _generate_test_suite(name, test_package_root, test_classes, class_rules = []):
+ """Generates a JUnit4 test suite pulling in all the referenced classes.
+
+ Args:
+ name: the name of the genrule and output test suite class.
+ test_package_root: the package string of the output test suite.
+ test_classes: the test classes included in the suite.
+ class_rules: optional list of classes to instantiate as a @ClassRule in the test suite.
+ """
+ lines = []
+ lines.append("package %s;" % test_package_root)
+ lines.append("")
+ if (class_rules):
+ lines.append("import org.junit.ClassRule;")
+ lines.append("import org.junit.runner.RunWith;")
+ lines.append("import org.junit.runners.Suite;")
+ lines.append("")
+ for test_class in test_classes:
+ lines.append("import %s;" % test_class)
+ lines.append("")
+ lines.append("@RunWith(Suite.class)")
+ lines.append("@Suite.SuiteClasses({")
+ for test_class in test_classes:
+ lines.append(" %s.class," % test_class.split(".")[-1])
+ lines.append("})")
+ lines.append("public class %s {" % name)
+ lines.append("")
+
+ i = 1
+ for class_rule in class_rules:
+ lines.append("@ClassRule")
+ lines.append("public static %s setupRule_%d = new %s();" % (class_rule, i, class_rule))
+ i += 1
+
+ lines.append("}")
+
+ contents = "\\n".join(lines)
+ native.genrule(
+ name = name,
+ cmd = "printf '%s' > $@" % contents,
+ outs = [name + ".java"],
+ )
+
+def _get_test_class(test_src, test_package_root):
+ """Returns the package string of the test class, beginning with the given root."""
+ full_path = PACKAGE_NAME + "/" + test_src
+ temp = full_path[:-5]
+ temp = temp.replace("/", ".")
+ i = temp.rfind(test_package_root)
+ if i < 0:
+ fail("Test source '%s' not under package root '%s'" % (full_path, test_package_root))
+ test_class = temp[i:]
+ return test_class
diff --git a/version.bzl b/version.bzl
index 96c8141..5cdb6a6 100644
--- a/version.bzl
+++ b/version.bzl
@@ -1,3 +1,3 @@
"""Version of the blaze plugin."""
-VERSION = "1.9.2"
+VERSION = "1.9.4"