Import of bazel plugin using copybara
PiperOrigin-RevId: 148774484
diff --git a/aswb/2.3/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java b/aswb/2.3/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java
index e59f375..2ec4852 100644
--- a/aswb/2.3/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java
+++ b/aswb/2.3/src/com/google/idea/blaze/android/project/BlazeFeatureEnableService.java
@@ -16,7 +16,9 @@
package com.google.idea.blaze.android.project;
import com.android.tools.idea.project.FeatureEnableService;
+import com.google.common.collect.ImmutableMap;
import com.google.idea.blaze.android.settings.BlazeAndroidUserSettings;
+import com.google.idea.blaze.base.logging.EventLogger;
import com.google.idea.blaze.base.settings.Blaze;
import com.google.idea.blaze.base.sync.data.BlazeProjectDataManager;
import com.google.idea.common.experiments.BoolExperiment;
@@ -24,6 +26,8 @@
/** Enable features supported by the blaze integration. */
public class BlazeFeatureEnableService extends FeatureEnableService {
+ private static final EventLogger logger = EventLogger.getInstance();
+
private static final BoolExperiment ENABLE_LAYOUT_EDITOR =
new BoolExperiment("enable.layout.editor", true);
@@ -34,10 +38,12 @@
@Override
public boolean isLayoutEditorEnabled(Project project) {
- return isLayoutEditorExperimentEnabled()
- && BlazeAndroidUserSettings.getInstance().getUseLayoutEditor()
- // Can't render if we don't have the data ready.
- && BlazeProjectDataManager.getInstance(project).getBlazeProjectData() != null;
+ boolean isEnabled =
+ isLayoutEditorExperimentEnabled()
+ && BlazeAndroidUserSettings.getInstance().getUseLayoutEditor();
+ boolean isReady = BlazeProjectDataManager.getInstance(project).getBlazeProjectData() != null;
+ logger.log("layout_editor", ImmutableMap.of("enabled", Boolean.toString(isEnabled)));
+ return isEnabled && isReady;
}
public static boolean isLayoutEditorExperimentEnabled() {
diff --git a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
index a33eb31..8c9ccc7 100644
--- a/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
+++ b/aswb/2.3/tests/unittests/com/google/idea/blaze/android/project/BlazeFeatureEnabledServiceTest.java
@@ -23,6 +23,7 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.android.settings.BlazeAndroidUserSettings;
import com.google.idea.blaze.base.BlazeTestCase;
+import com.google.idea.blaze.base.logging.EventLogger;
import com.google.idea.blaze.base.model.BlazeProjectData;
import com.google.idea.blaze.base.settings.Blaze.BuildSystem;
import com.google.idea.blaze.base.settings.BlazeImportSettings;
@@ -63,6 +64,8 @@
new BlazeImportSettings(null, null, null, null, null, BuildSystem.Blaze));
projectServices.register(BlazeImportSettingsManager.class, importSettingsManager);
+ registerExtensionPoint(
+ ExtensionPointName.create("com.google.idea.blaze.EventLogger"), EventLogger.class);
ExtensionPoint<FeatureEnableService> extensionPoint =
registerExtensionPoint(
ExtensionPointName.create("com.android.project.featureEnableService"),
diff --git a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeApkBuildStepMobileInstall.java b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeApkBuildStepMobileInstall.java
index 2082b77..2e69c17 100644
--- a/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeApkBuildStepMobileInstall.java
+++ b/aswb/src/com/google/idea/blaze/android/run/binary/mobileinstall/BlazeApkBuildStepMobileInstall.java
@@ -32,10 +32,10 @@
import com.google.idea.blaze.android.sync.model.BlazeAndroidSyncData;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.async.process.ExternalTask;
-import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
import com.google.idea.blaze.base.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.filecache.FileCaches;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.model.BlazeProjectData;
@@ -118,13 +118,14 @@
}
WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
+ BlazeApkDeployInfoProtoHelper deployInfoHelper =
+ new BlazeApkDeployInfoProtoHelper(project, buildFlags);
+ BuildResultHelper buildResultHelper = deployInfoHelper.getBuildResultHelper();
+
command
.addTargets(label)
.addBlazeFlags(buildFlags)
- .addBlazeFlags(BlazeFlags.EXPERIMENTAL_SHOW_ARTIFACTS);
-
- BlazeApkDeployInfoProtoHelper deployInfoHelper =
- new BlazeApkDeployInfoProtoHelper(project, buildFlags);
+ .addBlazeFlags(buildResultHelper.getBuildFlags());
SaveUtil.saveAllFiles();
int retVal =
@@ -132,8 +133,7 @@
.addBlazeCommand(command.build())
.context(context)
.stderr(
- LineProcessingOutputStream.of(
- deployInfoHelper.getLineProcessor(),
+ buildResultHelper.stderr(
new IssueOutputLineProcessor(project, context, workspaceRoot)))
.build()
.run();
diff --git a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java
index ffe8c6e..4de0387 100644
--- a/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java
+++ b/aswb/src/com/google/idea/blaze/android/run/deployinfo/BlazeApkDeployInfoProtoHelper.java
@@ -17,11 +17,9 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.android.manifest.ManifestParser;
-import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
-import com.google.idea.blaze.base.command.ExperimentalShowArtifactsLineProcessor;
+import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.command.info.BlazeInfo;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.scope.BlazeContext;
@@ -44,24 +42,23 @@
private final Project project;
private final WorkspaceRoot workspaceRoot;
private final ImmutableList<String> buildFlags;
- private final List<File> deployInfoFiles = Lists.newArrayList();
- private final LineProcessingOutputStream.LineProcessor lineProcessor =
- new ExperimentalShowArtifactsLineProcessor(
- deployInfoFiles, fileName -> fileName.endsWith(".deployinfo.pb"));
+ private final BuildResultHelper buildResultHelper;
public BlazeApkDeployInfoProtoHelper(Project project, ImmutableList<String> buildFlags) {
this.project = project;
this.buildFlags = buildFlags;
this.workspaceRoot = WorkspaceRoot.fromProject(project);
+ this.buildResultHelper =
+ BuildResultHelper.forFiles(fileName -> fileName.endsWith(".deployinfo.pb"));
}
- public LineProcessingOutputStream.LineProcessor getLineProcessor() {
- return lineProcessor;
+ public BuildResultHelper getBuildResultHelper() {
+ return buildResultHelper;
}
@Nullable
public BlazeAndroidDeployInfo readDeployInfo(BlazeContext context) {
- File deployInfoFile = Iterables.getOnlyElement(deployInfoFiles, null);
+ File deployInfoFile = Iterables.getOnlyElement(buildResultHelper.getBuildArtifacts(), null);
if (deployInfoFile == null) {
return null;
}
diff --git a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeApkBuildStepNormalBuild.java b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeApkBuildStepNormalBuild.java
index 1029f85..58daf4f 100644
--- a/aswb/src/com/google/idea/blaze/android/run/runner/BlazeApkBuildStepNormalBuild.java
+++ b/aswb/src/com/google/idea/blaze/android/run/runner/BlazeApkBuildStepNormalBuild.java
@@ -23,10 +23,9 @@
import com.google.idea.blaze.android.run.deployinfo.BlazeApkDeployInfoProtoHelper;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.async.process.ExternalTask;
-import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
import com.google.idea.blaze.base.command.BlazeCommand;
import com.google.idea.blaze.base.command.BlazeCommandName;
-import com.google.idea.blaze.base.command.BlazeFlags;
+import com.google.idea.blaze.base.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.filecache.FileCaches;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.model.primitives.Label;
@@ -67,14 +66,15 @@
Blaze.getBuildSystemProvider(project).getBinaryPath(), BlazeCommandName.BUILD);
WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
+ BlazeApkDeployInfoProtoHelper deployInfoHelper =
+ new BlazeApkDeployInfoProtoHelper(project, buildFlags);
+ BuildResultHelper buildResultHelper = deployInfoHelper.getBuildResultHelper();
+
command
.addTargets(label)
.addBlazeFlags("--output_groups=+android_deploy_info")
.addBlazeFlags(buildFlags)
- .addBlazeFlags(BlazeFlags.EXPERIMENTAL_SHOW_ARTIFACTS);
-
- BlazeApkDeployInfoProtoHelper deployInfoHelper =
- new BlazeApkDeployInfoProtoHelper(project, buildFlags);
+ .addBlazeFlags(buildResultHelper.getBuildFlags());
SaveUtil.saveAllFiles();
int retVal =
@@ -82,8 +82,7 @@
.addBlazeCommand(command.build())
.context(context)
.stderr(
- LineProcessingOutputStream.of(
- deployInfoHelper.getLineProcessor(),
+ buildResultHelper.stderr(
new IssueOutputLineProcessor(project, context, workspaceRoot)))
.build()
.run();
diff --git a/base/src/META-INF/blaze-base.xml b/base/src/META-INF/blaze-base.xml
index 781e35a..ed49eb9 100644
--- a/base/src/META-INF/blaze-base.xml
+++ b/base/src/META-INF/blaze-base.xml
@@ -326,6 +326,7 @@
<extensionPoint qualifiedName="com.google.idea.blaze.BlazeTestXmlFinderStrategy" interface="com.google.idea.blaze.base.run.testlogs.BlazeTestXmlFinderStrategy"/>
<extensionPoint qualifiedName="com.google.idea.blaze.BlazeTestEventsHandler" interface="com.google.idea.blaze.base.run.smrunner.BlazeTestEventsHandler"/>
<extensionPoint qualifiedName="com.google.idea.blaze.AttributeSpecificStringLiteralReferenceProvider" interface="com.google.idea.blaze.base.lang.buildfile.references.AttributeSpecificStringLiteralReferenceProvider"/>
+ <extensionPoint qualifiedName="com.google.idea.blaze.EventLogger" interface="com.google.idea.blaze.base.logging.EventLogger"/>
</extensionPoints>
<extensions defaultExtensionNs="com.google.idea.blaze">
diff --git a/base/src/com/google/idea/blaze/base/async/process/LineProcessingOutputStream.java b/base/src/com/google/idea/blaze/base/async/process/LineProcessingOutputStream.java
index 8aa44a8..5357fdf 100644
--- a/base/src/com/google/idea/blaze/base/async/process/LineProcessingOutputStream.java
+++ b/base/src/com/google/idea/blaze/base/async/process/LineProcessingOutputStream.java
@@ -15,11 +15,11 @@
*/
package com.google.idea.blaze.base.async.process;
-import com.google.common.collect.Lists;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.List;
-import org.jetbrains.annotations.NotNull;
/** An base output stream which marshals output into newline-delimited segments for processing. */
public final class LineProcessingOutputStream extends OutputStream {
@@ -31,25 +31,29 @@
*
* @return Whether line processing should continue
*/
- boolean processLine(@NotNull String line);
+ boolean processLine(String line);
}
- @NotNull private final StringBuffer stringBuffer = new StringBuffer();
+ private final StringBuffer stringBuffer = new StringBuffer();
private volatile boolean closed;
- @NotNull private final List<LineProcessor> lineProcessors;
+ private final ImmutableList<LineProcessor> lineProcessors;
- LineProcessingOutputStream(@NotNull LineProcessor... lineProcessors) {
- this.lineProcessors = Lists.newArrayList(lineProcessors);
+ LineProcessingOutputStream(ImmutableList<LineProcessor> lineProcessors) {
+ this.lineProcessors = lineProcessors;
}
- public static LineProcessingOutputStream of(@NotNull LineProcessor... lineProcessors) {
+ public static LineProcessingOutputStream of(LineProcessor... lineProcessors) {
+ return new LineProcessingOutputStream(ImmutableList.copyOf(lineProcessors));
+ }
+
+ public static LineProcessingOutputStream of(ImmutableList<LineProcessor> lineProcessors) {
return new LineProcessingOutputStream(lineProcessors);
}
@Override
public synchronized void write(byte[] b, int off, int len) {
if (!closed) {
- String text = new String(b, off, len);
+ String text = new String(b, off, len, UTF_8);
stringBuffer.append(text);
while (true) {
diff --git a/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelper.java b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelper.java
new file mode 100644
index 0000000..9adf5e2
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelper.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.base.command.buildresult;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream.LineProcessor;
+import com.google.idea.common.experiments.BoolExperiment;
+import java.io.File;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.function.Predicate;
+
+/** Assists in getting build artifacts from a build operation. */
+public interface BuildResultHelper {
+ // This experiment does *not* work yet and should remain off
+ BoolExperiment USE_BEP = new BoolExperiment("use.bep", false);
+
+ /**
+ * Constructs a new build result helper.
+ *
+ * @param files A filter for the output artifacts you are interested in.
+ */
+ static BuildResultHelper forFiles(Predicate<String> files) {
+ return USE_BEP.getValue()
+ ? new BuildResultHelperBep(files)
+ : new BuildResultHelperStderr(files);
+ }
+
+ /**
+ * Returns the build flags necessary for the build result helper to work.
+ *
+ * <p>The user must add these flags to their build command.
+ */
+ List<String> getBuildFlags();
+
+ /**
+ * Returns an output stream to be passed to the external task's stderr.
+ *
+ * <p>The user must pipe blaze's stderr to this output stream.
+ *
+ * @param lineProcessors Any additional line processors you want on stderr output.
+ */
+ OutputStream stderr(LineProcessor... lineProcessors);
+
+ /**
+ * Returns the build result. May only be called once the build is complete, or no artifacts will
+ * be returned.
+ *
+ * @return The build artifacts from the build operation.
+ */
+ ImmutableList<File> getBuildArtifacts();
+}
diff --git a/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperBep.java b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperBep.java
new file mode 100644
index 0000000..8a32e85
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperBep.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.base.command.buildresult;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream.LineProcessor;
+import com.google.repackaged.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEvent;
+import com.google.repackaged.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId;
+import com.google.repackaged.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildEventId.IdCase;
+import com.intellij.openapi.diagnostic.Logger;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.UUID;
+import java.util.function.Predicate;
+
+/**
+ * Build event protocol implementation to get build results.
+ *
+ * <p>The build even protocol (BEP for short) is a proto-based protocol used by bazel to communicate
+ * build events.
+ */
+class BuildResultHelperBep implements BuildResultHelper {
+ private static final Logger logger = Logger.getInstance(BuildResultHelperBep.class);
+ private final File outputFile;
+ private final Predicate<String> fileFilter;
+ private ImmutableList<File> result;
+
+ BuildResultHelperBep(Predicate<String> fileFilter) {
+ this.fileFilter = fileFilter;
+ File tempDir = new File(System.getProperty("java.io.tmpdir"));
+ String suffix = UUID.randomUUID().toString();
+ String fileName = "intellij-bep-" + suffix;
+ this.outputFile = new File(tempDir, fileName);
+ }
+
+ @Override
+ public List<String> getBuildFlags() {
+ return ImmutableList.of("--experimental_build_event_binary_file=" + outputFile.getPath());
+ }
+
+ @Override
+ public OutputStream stderr(LineProcessor... lineProcessors) {
+ return LineProcessingOutputStream.of(ImmutableList.copyOf(lineProcessors));
+ }
+
+ @Override
+ public ImmutableList<File> getBuildArtifacts() {
+ if (result == null) {
+ result = readResult();
+ }
+ return result;
+ }
+
+ private ImmutableList<File> readResult() {
+ ImmutableList.Builder<File> result = ImmutableList.builder();
+ try (InputStream inputStream = new BufferedInputStream(new FileInputStream(outputFile))) {
+ BuildEvent buildEvent;
+ while ((buildEvent = BuildEvent.parseDelimitedFrom(inputStream)) != null) {
+ BuildEventId buildEventId = buildEvent.getId();
+ // Note: This doesn't actually work. BEP does not issue these for actions
+ // that don't execute during the build, so we can't find the files
+ // for a no-op build the way we can for --experimental_show_artifacts
+ if (buildEventId.getIdCase() == IdCase.ACTION_COMPLETED) {
+ String output = buildEventId.getActionCompleted().getPrimaryOutput();
+ if (fileFilter.test(output)) {
+ result.add(new File(output));
+ }
+ }
+ }
+ } catch (IOException e) {
+ logger.error(e);
+ return ImmutableList.of();
+ }
+ if (!outputFile.delete()) {
+ logger.warn("Could not delete BEP output file: " + outputFile);
+ }
+ return result.build();
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperStderr.java b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperStderr.java
new file mode 100644
index 0000000..ef34dd6
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/command/buildresult/BuildResultHelperStderr.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.base.command.buildresult;
+
+import com.google.common.collect.ImmutableList;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
+import com.google.idea.blaze.base.async.process.LineProcessingOutputStream.LineProcessor;
+import com.google.idea.blaze.base.command.BlazeFlags;
+import java.io.File;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.function.Predicate;
+
+class BuildResultHelperStderr implements BuildResultHelper {
+ private final ImmutableList.Builder<File> buildArtifacts = ImmutableList.builder();
+ private final ExperimentalShowArtifactsLineProcessor experimentalShowArtifactsLineProcessor;
+ private ImmutableList<File> result;
+
+ BuildResultHelperStderr(Predicate<String> fileFilter) {
+ experimentalShowArtifactsLineProcessor =
+ new ExperimentalShowArtifactsLineProcessor(buildArtifacts, fileFilter);
+ }
+
+ @Override
+ public List<String> getBuildFlags() {
+ return ImmutableList.of(BlazeFlags.EXPERIMENTAL_SHOW_ARTIFACTS);
+ }
+
+ @Override
+ public OutputStream stderr(LineProcessor... lineProcessors) {
+ return LineProcessingOutputStream.of(
+ ImmutableList.<LineProcessor>builder()
+ .add(experimentalShowArtifactsLineProcessor)
+ .add(lineProcessors)
+ .build());
+ }
+
+ @Override
+ public ImmutableList<File> getBuildArtifacts() {
+ if (result == null) {
+ result = buildArtifacts.build();
+ }
+ return result;
+ }
+}
diff --git a/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java b/base/src/com/google/idea/blaze/base/command/buildresult/ExperimentalShowArtifactsLineProcessor.java
similarity index 78%
rename from base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java
rename to base/src/com/google/idea/blaze/base/command/buildresult/ExperimentalShowArtifactsLineProcessor.java
index 9698b62..609867c 100644
--- a/base/src/com/google/idea/blaze/base/command/ExperimentalShowArtifactsLineProcessor.java
+++ b/base/src/com/google/idea/blaze/base/command/buildresult/ExperimentalShowArtifactsLineProcessor.java
@@ -13,29 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.google.idea.blaze.base.command;
+package com.google.idea.blaze.base.command.buildresult;
+import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.async.process.LineProcessingOutputStream;
import java.io.File;
-import java.util.List;
import java.util.function.Predicate;
import org.jetbrains.annotations.NotNull;
/** Collects the output of --experimental_show_artifacts */
-public class ExperimentalShowArtifactsLineProcessor
- implements LineProcessingOutputStream.LineProcessor {
+class ExperimentalShowArtifactsLineProcessor implements LineProcessingOutputStream.LineProcessor {
private static final String OUTPUT_START = "Build artifacts:";
private static final String OUTPUT_MARKER = ">>>";
- private final List<File> fileList;
+ private final ImmutableList.Builder<File> fileList;
private final Predicate<String> filter;
private boolean afterBuildResult = false;
- public ExperimentalShowArtifactsLineProcessor(List<File> fileList) {
- this(fileList, (value) -> true);
- }
-
- public ExperimentalShowArtifactsLineProcessor(List<File> fileList, Predicate<String> filter) {
+ ExperimentalShowArtifactsLineProcessor(
+ ImmutableList.Builder<File> fileList, Predicate<String> filter) {
this.fileList = fileList;
this.filter = filter;
}
diff --git a/base/src/com/google/idea/blaze/base/issueparser/BlazeIssueParser.java b/base/src/com/google/idea/blaze/base/issueparser/BlazeIssueParser.java
index 2ebd868..df8a28b 100644
--- a/base/src/com/google/idea/blaze/base/issueparser/BlazeIssueParser.java
+++ b/base/src/com/google/idea/blaze/base/issueparser/BlazeIssueParser.java
@@ -36,11 +36,11 @@
import java.util.regex.Pattern;
import javax.annotation.Nullable;
-
/** Parses blaze output for compile errors. */
public class BlazeIssueParser {
- private static class ParseResult {
+ /** Result from parsing the current line */
+ public static class ParseResult {
public static final ParseResult NEEDS_MORE_INPUT = new ParseResult(true, null);
@@ -132,7 +132,10 @@
}
/** Falls back to returning -1 if no integer can be parsed. */
- public static int parseOptionalInt(String intString) {
+ public static int parseOptionalInt(@Nullable String intString) {
+ if (intString == null) {
+ return -1;
+ }
try {
return Integer.parseInt(intString);
} catch (NumberFormatException e) {
diff --git a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildElementValidation.java b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildElementValidation.java
index 138908c..c069bb9 100644
--- a/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildElementValidation.java
+++ b/base/src/com/google/idea/blaze/base/lang/buildfile/validation/BuildElementValidation.java
@@ -15,6 +15,7 @@
*/
package com.google.idea.blaze.base.lang.buildfile.validation;
+import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.lang.buildfile.psi.DictionaryLiteral;
import com.google.idea.blaze.base.lang.buildfile.psi.FunctionStatement;
import com.google.idea.blaze.base.lang.buildfile.psi.GlobExpression;
@@ -38,14 +39,21 @@
private static final EnumSet<Build.Attribute.Discriminator> LIST_TYPES =
EnumSet.of(
Discriminator.STRING_LIST,
+ Discriminator.DISTRIBUTION_SET,
Discriminator.LABEL_LIST,
Discriminator.OUTPUT_LIST,
Discriminator.FILESET_ENTRY_LIST,
Discriminator.INTEGER_LIST,
- Discriminator.LICENSE);
+ Discriminator.LICENSE,
+ Discriminator.SELECTOR_LIST);
private static final EnumSet<Build.Attribute.Discriminator> DICT_TYPES =
- EnumSet.of(Discriminator.LABEL_LIST_DICT, Discriminator.STRING_LIST_DICT);
+ EnumSet.of(
+ Discriminator.LABEL_LIST_DICT,
+ Discriminator.STRING_DICT,
+ Discriminator.STRING_LIST_DICT,
+ Discriminator.STRING_DICT_UNARY,
+ Discriminator.LABEL_DICT_UNARY);
private static final EnumSet<Build.Attribute.Discriminator> STRING_TYPES =
EnumSet.of(
@@ -58,9 +66,20 @@
private static final EnumSet<Build.Attribute.Discriminator> INTEGER_TYPES =
EnumSet.of(Discriminator.INTEGER, Discriminator.BOOLEAN, Discriminator.TRISTATE);
+ // This enum list is duplicated several times through Bazel source code. In some places there are
+ // additional items not covered here. Don't show spurious errors when more items are added.
+ private static final EnumSet<Build.Attribute.Discriminator> HANDLED_TYPES =
+ EnumSet.copyOf(
+ ImmutableList.<Discriminator>builder()
+ .addAll(LIST_TYPES)
+ .addAll(DICT_TYPES)
+ .addAll(STRING_TYPES)
+ .addAll(INTEGER_TYPES)
+ .build());
+
/** Returns false iff we know with certainty that the element cannot resolve to the given type. */
public static boolean possiblyValidType(PsiElement element, Build.Attribute.Discriminator type) {
- if (type == Discriminator.UNKNOWN) {
+ if (!HANDLED_TYPES.contains(type)) {
return true;
}
if (element instanceof ListLiteral || element instanceof GlobExpression) {
diff --git a/base/src/com/google/idea/blaze/base/logging/EventLogger.java b/base/src/com/google/idea/blaze/base/logging/EventLogger.java
new file mode 100644
index 0000000..5f2a701
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/logging/EventLogger.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.base.logging;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import java.util.Map;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Forwards the event logs to an applicable receiver extension or discard them if no applicable
+ * receivers exist.
+ */
+public interface EventLogger {
+ ExtensionPointName<EventLogger> EP_NAME =
+ new ExtensionPointName<>("com.google.idea.blaze.EventLogger");
+
+ static EventLogger getInstance() {
+ for (EventLogger logger : EP_NAME.getExtensions()) {
+ if (logger.isApplicable()) {
+ return logger;
+ }
+ }
+ return NullEventLogger.SINGLETON;
+ }
+
+ boolean isApplicable();
+
+ default void log(String eventType, Map<String, String> keyValues) {
+ log(eventType, keyValues, null);
+ }
+
+ default void log(
+ String eventType, Map<String, String> keyValues, @Nullable Long timestampInMillis) {
+ log(eventType, keyValues, timestampInMillis, null);
+ }
+
+ void log(
+ String eventType,
+ Map<String, String> keyValues,
+ @Nullable Long timestampInMillis,
+ @Nullable Long durationInNanos);
+}
diff --git a/base/src/com/google/idea/blaze/base/logging/NullEventLogger.java b/base/src/com/google/idea/blaze/base/logging/NullEventLogger.java
new file mode 100644
index 0000000..15562ab
--- /dev/null
+++ b/base/src/com/google/idea/blaze/base/logging/NullEventLogger.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.base.logging;
+
+import java.util.Map;
+import org.jetbrains.annotations.Nullable;
+
+/** No-op logger used when no logger is not available to receive logs. */
+public class NullEventLogger implements EventLogger {
+ static final NullEventLogger SINGLETON = new NullEventLogger();
+
+ private NullEventLogger() {}
+
+ @Override
+ public boolean isApplicable() {
+ return true;
+ }
+
+ @Override
+ public void log(
+ String eventType,
+ Map<String, String> keyValues,
+ @Nullable Long timestampInMillis,
+ @Nullable Long durationInNanos) {}
+}
diff --git a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeTestEventsHandler.java b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeTestEventsHandler.java
index 7bb4325..3ecdeea 100644
--- a/base/src/com/google/idea/blaze/base/run/smrunner/BlazeTestEventsHandler.java
+++ b/base/src/com/google/idea/blaze/base/run/smrunner/BlazeTestEventsHandler.java
@@ -116,11 +116,11 @@
public String testLocationUrl(
@Nullable Kind kind, String parentSuite, String name, @Nullable String className) {
- String base = SmRunnerUtils.GENERIC_TEST_PROTOCOL + URLUtil.SCHEME_SEPARATOR + name;
+ String base = SmRunnerUtils.GENERIC_TEST_PROTOCOL + URLUtil.SCHEME_SEPARATOR;
if (Strings.isNullOrEmpty(className)) {
- return base;
+ return base + name;
}
- return base + SmRunnerUtils.TEST_NAME_PARTS_SPLITTER + className;
+ return base + className + SmRunnerUtils.TEST_NAME_PARTS_SPLITTER + name;
}
/** Whether to skip logging a {@link TestSuite}. */
diff --git a/base/src/com/google/idea/blaze/base/settings/ui/ProjectViewUi.java b/base/src/com/google/idea/blaze/base/settings/ui/ProjectViewUi.java
index 5023368..ae6a917 100644
--- a/base/src/com/google/idea/blaze/base/settings/ui/ProjectViewUi.java
+++ b/base/src/com/google/idea/blaze/base/settings/ui/ProjectViewUi.java
@@ -133,7 +133,7 @@
return editor;
}
- public void fillUi(JPanel canvas, int indentLevel) {
+ public void fillUi(JPanel canvas) {
String tooltip =
"Enter a project view descriptor file."
+ (Blaze.defaultBuildSystem() == BuildSystem.Blaze
@@ -149,9 +149,9 @@
JBLabel labelsLabel = new JBLabel("Project View");
labelsLabel.setToolTipText(tooltip);
- canvas.add(labelsLabel, UiUtil.getFillLineConstraints(indentLevel));
+ canvas.add(labelsLabel, UiUtil.getFillLineConstraints(0));
- canvas.add(projectViewEditor.getComponent(), UiUtil.getFillLineConstraints(indentLevel));
+ canvas.add(projectViewEditor.getComponent(), UiUtil.getFillLineConstraints(0));
useShared = new JCheckBox(USE_SHARED_PROJECT_VIEW);
useShared.addActionListener(
@@ -162,7 +162,7 @@
}
updateTextAreasEnabled();
});
- canvas.add(useShared, UiUtil.getFillLineConstraints(indentLevel));
+ canvas.add(useShared, UiUtil.getFillLineConstraints(0));
}
public void init(
@@ -185,10 +185,7 @@
}
useShared.setSelected(useSharedProjectView);
-
- if (sharedProjectViewText == null) {
- useShared.setEnabled(false);
- }
+ useShared.setEnabled(sharedProjectViewText != null);
setDummyWorkspacePathResolverProvider(this.workspacePathResolver);
setProjectViewText(projectViewText);
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 ac83b63..beb53db 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
@@ -30,7 +30,7 @@
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.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.filecache.FileDiffer;
import com.google.idea.blaze.base.ideinfo.TargetIdeInfo;
import com.google.idea.blaze.base.ideinfo.TargetKey;
@@ -190,36 +190,34 @@
context.push(
new TimingScope(String.format("Execute%sCommand", Blaze.buildSystemName(project))));
- List<File> result = Lists.newArrayList();
+ String fileExtension = aspectStrategy.getAspectOutputFileExtension();
+ String gzFileExtension = fileExtension + ".gz";
+ Predicate<String> fileFilter =
+ fileName -> fileName.endsWith(fileExtension) || fileName.endsWith(gzFileExtension);
+ BuildResultHelper buildResultHelper = BuildResultHelper.forFiles(fileFilter);
BlazeCommand.Builder blazeCommandBuilder =
BlazeCommand.builder(getBinaryPath(project), BlazeCommandName.BUILD);
blazeCommandBuilder.addTargets(targets);
blazeCommandBuilder.addBlazeFlags(BlazeFlags.KEEP_GOING);
blazeCommandBuilder
- .addBlazeFlags(BlazeFlags.EXPERIMENTAL_SHOW_ARTIFACTS)
+ .addBlazeFlags(buildResultHelper.getBuildFlags())
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet));
aspectStrategy.modifyIdeInfoCommand(blazeCommandBuilder);
- String fileExtension = aspectStrategy.getAspectOutputFileExtension();
- String gzFileExtension = fileExtension + ".gz";
- Predicate<String> fileFilter =
- fileName -> fileName.endsWith(fileExtension) || fileName.endsWith(gzFileExtension);
-
int retVal =
ExternalTask.builder(workspaceRoot)
.addBlazeCommand(blazeCommandBuilder.build())
.context(context)
.stderr(
- LineProcessingOutputStream.of(
- new ExperimentalShowArtifactsLineProcessor(result, fileFilter),
+ buildResultHelper.stderr(
new IssueOutputLineProcessor(project, context, workspaceRoot)))
.build()
.run();
BuildResult buildResult = BuildResult.fromExitCode(retVal);
- return new IdeInfoResult(result, buildResult);
+ return new IdeInfoResult(buildResultHelper.getBuildArtifacts(), buildResult);
});
}
diff --git a/base/src/com/google/idea/blaze/base/wizard2/BlazeSelectProjectViewOption.java b/base/src/com/google/idea/blaze/base/wizard2/BlazeSelectProjectViewOption.java
index 353ecb4..51229f0 100644
--- a/base/src/com/google/idea/blaze/base/wizard2/BlazeSelectProjectViewOption.java
+++ b/base/src/com/google/idea/blaze/base/wizard2/BlazeSelectProjectViewOption.java
@@ -37,9 +37,9 @@
return false;
}
- /** Returns the default project name */
- default String getDefaultProjectName(String workspaceName) {
- return workspaceName;
+ /** Returns the directory we're importing from, if applicable. */
+ default String getImportDirectory() {
+ return null;
}
void commit();
diff --git a/base/src/com/google/idea/blaze/base/wizard2/BlazeSelectWorkspaceOption.java b/base/src/com/google/idea/blaze/base/wizard2/BlazeSelectWorkspaceOption.java
index 11bf115..3c9a601 100644
--- a/base/src/com/google/idea/blaze/base/wizard2/BlazeSelectWorkspaceOption.java
+++ b/base/src/com/google/idea/blaze/base/wizard2/BlazeSelectWorkspaceOption.java
@@ -34,6 +34,9 @@
/** @return the name of the workspace. Used to generate default project names. */
String getWorkspaceName();
+ /** @return the name of the 'branch', if applicable */
+ String getBranchName();
+
BuildSystem getBuildSystemForWorkspace();
void commit() throws BlazeProjectCommitException;
diff --git a/base/src/com/google/idea/blaze/base/wizard2/GenerateFromBuildFileSelectProjectViewOption.java b/base/src/com/google/idea/blaze/base/wizard2/GenerateFromBuildFileSelectProjectViewOption.java
index 341d023..6e4e74e 100644
--- a/base/src/com/google/idea/blaze/base/wizard2/GenerateFromBuildFileSelectProjectViewOption.java
+++ b/base/src/com/google/idea/blaze/base/wizard2/GenerateFromBuildFileSelectProjectViewOption.java
@@ -120,9 +120,9 @@
}
@Override
- public String getDefaultProjectName(String workspaceName) {
+ public String getImportDirectory() {
File buildFileParent = new File(getBuildFilePath()).getParentFile();
- return buildFileParent != null ? buildFileParent.getName() : workspaceName;
+ return buildFileParent != null ? buildFileParent.getName() : null;
}
@Override
diff --git a/base/src/com/google/idea/blaze/base/wizard2/ImportFromWorkspaceProjectViewOption.java b/base/src/com/google/idea/blaze/base/wizard2/ImportFromWorkspaceProjectViewOption.java
index fe43d1c..14a07e0 100644
--- a/base/src/com/google/idea/blaze/base/wizard2/ImportFromWorkspaceProjectViewOption.java
+++ b/base/src/com/google/idea/blaze/base/wizard2/ImportFromWorkspaceProjectViewOption.java
@@ -109,11 +109,11 @@
}
@Override
- public String getDefaultProjectName(String workspaceName) {
+ public String getImportDirectory() {
File projectViewFile = new File(getProjectViewPath());
File projectViewDirectory = projectViewFile.getParentFile();
if (projectViewDirectory == null) {
- return workspaceName;
+ return null;
}
return projectViewDirectory.getName();
}
diff --git a/base/src/com/google/idea/blaze/base/wizard2/UseExistingBazelWorkspaceOption.java b/base/src/com/google/idea/blaze/base/wizard2/UseExistingBazelWorkspaceOption.java
index 51af079..de9d125 100644
--- a/base/src/com/google/idea/blaze/base/wizard2/UseExistingBazelWorkspaceOption.java
+++ b/base/src/com/google/idea/blaze/base/wizard2/UseExistingBazelWorkspaceOption.java
@@ -117,6 +117,11 @@
}
@Override
+ public String getBranchName() {
+ return null;
+ }
+
+ @Override
public BlazeValidationResult validate() {
if (getDirectory().isEmpty()) {
return BlazeValidationResult.failure("Please select a workspace");
diff --git a/base/src/com/google/idea/blaze/base/wizard2/ui/BlazeEditProjectViewControl.java b/base/src/com/google/idea/blaze/base/wizard2/ui/BlazeEditProjectViewControl.java
index 70001eb..6c23cf1 100644
--- a/base/src/com/google/idea/blaze/base/wizard2/ui/BlazeEditProjectViewControl.java
+++ b/base/src/com/google/idea/blaze/base/wizard2/ui/BlazeEditProjectViewControl.java
@@ -50,6 +50,7 @@
import com.google.idea.blaze.base.wizard2.ProjectDataDirectoryValidator;
import com.google.idea.common.experiments.BoolExperiment;
import com.intellij.ide.RecentProjectsManager;
+import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.diagnostic.Logger;
@@ -69,8 +70,10 @@
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
+import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
+import javax.swing.JRadioButton;
import javax.swing.JTextField;
import org.jetbrains.annotations.NotNull;
@@ -83,6 +86,8 @@
private static final BoolExperiment allowAddprojectViewDefaultValues =
new BoolExperiment("allow.add.project.view.default.values", true);
+ private static final String LAST_WORKSPACE_MODE_PROPERTY =
+ "blaze.edit.project.view.control.last.workspace.mode";
private final JPanel component;
private final String buildSystemName;
@@ -90,14 +95,27 @@
private TextFieldWithBrowseButton projectDataDirField;
private JTextField projectNameField;
+ private JRadioButton workspaceDefaultNameOption;
+ private JRadioButton branchDefaultNameOption;
+ private JRadioButton importDirectoryDefaultNameOption;
private HashCode paramsHash;
private WorkspaceRoot workspaceRoot;
private WorkspacePathResolver workspacePathResolver;
+ private BlazeSelectWorkspaceOption workspaceOption;
+ private BlazeSelectProjectViewOption projectViewOption;
+ private boolean isInitialising;
+ private boolean defaultWorkspaceNameModeExplicitlySet;
+
+ private enum InferDefaultNameMode {
+ FromWorkspace,
+ FromBranch,
+ FromImportDirectory,
+ }
public BlazeEditProjectViewControl(BlazeNewProjectBuilder builder, Disposable parentDisposable) {
this.projectViewUi = new ProjectViewUi(parentDisposable);
JPanel component = new JPanelProvidingProject(ProjectViewUi.getProject(), new GridBagLayout());
- fillUi(component, 0);
+ fillUi(component);
update(builder);
UiUtil.fillBottom(component);
this.component = component;
@@ -108,12 +126,12 @@
return component;
}
- private void fillUi(JPanel canvas, int indentLevel) {
+ private void fillUi(JPanel canvas) {
JLabel projectDataDirLabel = new JBLabel("Project data directory:");
Dimension minSize = ProjectViewUi.getMinimumSize();
- // Add 120 pixels so we have room for our extra fields
- minSize.setSize(minSize.width, minSize.height + 120);
+ // Add pixels so we have room for our extra fields
+ minSize.setSize(minSize.width, minSize.height + 180);
canvas.setMinimumSize(minSize);
canvas.setPreferredSize(minSize);
@@ -131,7 +149,7 @@
projectDataDirField.setToolTipText(dataDirToolTipText);
projectDataDirLabel.setToolTipText(dataDirToolTipText);
- canvas.add(projectDataDirLabel, UiUtil.getLabelConstraints(indentLevel));
+ canvas.add(projectDataDirLabel, UiUtil.getLabelConstraints(0));
canvas.add(projectDataDirField, UiUtil.getFillLineConstraints(0));
JLabel projectNameLabel = new JLabel("Project name:");
@@ -139,17 +157,32 @@
final String projectNameToolTipText = "Project display name.";
projectNameField.setToolTipText(projectNameToolTipText);
projectNameLabel.setToolTipText(projectNameToolTipText);
- canvas.add(projectNameLabel, UiUtil.getLabelConstraints(indentLevel));
+ canvas.add(projectNameLabel, UiUtil.getLabelConstraints(0));
canvas.add(projectNameField, UiUtil.getFillLineConstraints(0));
- projectViewUi.fillUi(canvas, indentLevel);
+ JLabel defaultNameLabel = new JLabel("Infer name from:");
+ workspaceDefaultNameOption = new JRadioButton("Workspace");
+ branchDefaultNameOption = new JRadioButton("Branch");
+ importDirectoryDefaultNameOption = new JRadioButton("Import Directory");
+ workspaceDefaultNameOption.addItemListener(e -> inferDefaultNameModeSelectionChanged());
+ branchDefaultNameOption.addItemListener(e -> inferDefaultNameModeSelectionChanged());
+ importDirectoryDefaultNameOption.addItemListener(e -> inferDefaultNameModeSelectionChanged());
+ ButtonGroup buttonGroup = new ButtonGroup();
+ buttonGroup.add(workspaceDefaultNameOption);
+ buttonGroup.add(branchDefaultNameOption);
+ buttonGroup.add(importDirectoryDefaultNameOption);
+ canvas.add(defaultNameLabel, UiUtil.getLabelConstraints(0));
+ canvas.add(workspaceDefaultNameOption, UiUtil.getLabelConstraints(0));
+ canvas.add(branchDefaultNameOption, UiUtil.getLabelConstraints(0));
+ canvas.add(importDirectoryDefaultNameOption, UiUtil.getLabelConstraints(0));
+ canvas.add(new JPanel(), UiUtil.getFillLineConstraints(0));
+
+ projectViewUi.fillUi(canvas);
}
public void update(BlazeNewProjectBuilder builder) {
- BlazeSelectWorkspaceOption workspaceOption = builder.getWorkspaceOption();
- BlazeSelectProjectViewOption projectViewOption = builder.getProjectViewOption();
- String defaultProjectName =
- projectViewOption.getDefaultProjectName(workspaceOption.getWorkspaceName());
+ this.workspaceOption = builder.getWorkspaceOption();
+ this.projectViewOption = builder.getProjectViewOption();
WorkspaceRoot workspaceRoot = workspaceOption.getWorkspaceRoot();
WorkspacePath workspacePath = projectViewOption.getSharedProjectView();
String initialProjectViewText = projectViewOption.getInitialProjectViewText();
@@ -161,7 +194,6 @@
HashCode hashCode =
Hashing.md5()
.newHasher()
- .putUnencodedChars(defaultProjectName)
.putUnencodedChars(workspaceRoot.toString())
.putUnencodedChars(workspacePath != null ? workspacePath.toString() : "")
.putUnencodedChars(initialProjectViewText != null ? initialProjectViewText : "")
@@ -171,13 +203,14 @@
// If any params have changed, reinit the control
if (!hashCode.equals(paramsHash)) {
this.paramsHash = hashCode;
+ this.isInitialising = true;
init(
- defaultProjectName,
workspaceRoot,
workspacePathResolver,
workspacePath,
initialProjectViewText,
allowAddDefaultValues);
+ this.isInitialising = false;
}
}
@@ -199,7 +232,6 @@
}
private void init(
- String defaultProjectName,
WorkspaceRoot workspaceRoot,
WorkspacePathResolver workspacePathResolver,
@Nullable WorkspacePath sharedProjectView,
@@ -209,12 +241,11 @@
initialProjectViewText =
modifyInitialProjectView(initialProjectViewText, workspacePathResolver);
}
-
this.workspaceRoot = workspaceRoot;
this.workspacePathResolver = workspacePathResolver;
- projectNameField.setText(defaultProjectName);
- String defaultDataDir = getDefaultProjectDataDirectory(defaultProjectName);
- projectDataDirField.setText(defaultDataDir);
+
+ updateDefaultProjectNameUiState();
+ updateDefaultProjectName();
String projectViewText = "";
File sharedProjectViewFile = null;
@@ -246,6 +277,82 @@
false /* allowEditShared - not allowed during import */);
}
+ private void updateDefaultProjectNameUiState() {
+ workspaceDefaultNameOption.setEnabled(true);
+ branchDefaultNameOption.setEnabled(workspaceOption.getBranchName() != null);
+ importDirectoryDefaultNameOption.setEnabled(projectViewOption.getImportDirectory() != null);
+
+ InferDefaultNameMode inferDefaultNameMode = InferDefaultNameMode.FromImportDirectory;
+ try {
+ String lastModeString =
+ PropertiesComponent.getInstance().getValue(LAST_WORKSPACE_MODE_PROPERTY);
+ if (lastModeString != null) {
+ inferDefaultNameMode = InferDefaultNameMode.valueOf(lastModeString);
+ }
+ } catch (IllegalArgumentException e) {
+ // Ignore
+ }
+ switch (inferDefaultNameMode) {
+ case FromWorkspace:
+ workspaceDefaultNameOption.setSelected(true);
+ break;
+ case FromBranch:
+ if (workspaceOption.getBranchName() != null) {
+ branchDefaultNameOption.setSelected(true);
+ } else {
+ workspaceDefaultNameOption.setSelected(true);
+ }
+ break;
+ case FromImportDirectory:
+ if (projectViewOption.getImportDirectory() != null) {
+ importDirectoryDefaultNameOption.setSelected(true);
+ } else {
+ workspaceDefaultNameOption.setSelected(true);
+ }
+ break;
+ default:
+ throw new AssertionError("Illegal workspace name mode");
+ }
+ }
+
+ private InferDefaultNameMode getInferDefaultNameMode() {
+ if (workspaceDefaultNameOption.isSelected()) {
+ return InferDefaultNameMode.FromWorkspace;
+ } else if (branchDefaultNameOption.isSelected()) {
+ return InferDefaultNameMode.FromBranch;
+ } else if (importDirectoryDefaultNameOption.isSelected()) {
+ return InferDefaultNameMode.FromImportDirectory;
+ }
+ return InferDefaultNameMode.FromWorkspace;
+ }
+
+ private void inferDefaultNameModeSelectionChanged() {
+ if (!isInitialising) {
+ updateDefaultProjectName();
+ this.defaultWorkspaceNameModeExplicitlySet = true;
+ }
+ }
+
+ private void updateDefaultProjectName() {
+ String defaultProjectName = getDefaultName(getInferDefaultNameMode());
+ projectNameField.setText(defaultProjectName);
+ String defaultDataDir = getDefaultProjectDataDirectory(defaultProjectName);
+ projectDataDirField.setText(defaultDataDir);
+ }
+
+ private String getDefaultName(InferDefaultNameMode inferDefaultNameMode) {
+ switch (inferDefaultNameMode) {
+ case FromWorkspace:
+ return workspaceOption.getWorkspaceName();
+ case FromBranch:
+ return workspaceOption.getBranchName();
+ case FromImportDirectory:
+ return projectViewOption.getImportDirectory();
+ default:
+ throw new AssertionError("Invalid workspace name mode.");
+ }
+ }
+
private static String getDefaultProjectDataDirectory(String projectName) {
File defaultDataDirectory = new File(getDefaultProjectsDirectory());
File desiredLocation = new File(defaultDataDirectory, projectName);
@@ -452,4 +559,12 @@
.setProjectName(projectName)
.setProjectDataDirectory(projectDataDirectory);
}
+
+ public void commit() {
+ if (defaultWorkspaceNameModeExplicitlySet) {
+ InferDefaultNameMode inferDefaultNameMode = getInferDefaultNameMode();
+ PropertiesComponent.getInstance()
+ .setValue(LAST_WORKSPACE_MODE_PROPERTY, inferDefaultNameMode.toString());
+ }
+ }
}
diff --git a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/BuiltInRuleAnnotatorTest.java b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/BuiltInRuleAnnotatorTest.java
index 28eece6..2459af6 100644
--- a/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/BuiltInRuleAnnotatorTest.java
+++ b/base/tests/integrationtests/com/google/idea/blaze/base/lang/buildfile/validation/BuiltInRuleAnnotatorTest.java
@@ -55,6 +55,9 @@
private static final AttributeDefinition NEVERLINK_ATTRIBUTE =
new AttributeDefinition("neverlink", Discriminator.BOOLEAN, false, null, null);
+ private static final AttributeDefinition VALUES_ATTRIBUTE =
+ new AttributeDefinition("values", Discriminator.STRING_DICT, true, null, null);
+
private static final RuleDefinition JAVA_TEST =
new RuleDefinition(
"java_test",
@@ -62,6 +65,12 @@
"name", NAME_ATTRIBUTE, "srcs", SRCS_ATTRIBUTE, "neverlink", NEVERLINK_ATTRIBUTE),
null);
+ private static final RuleDefinition CONFIG_SETTING =
+ new RuleDefinition(
+ "config_setting",
+ ImmutableMap.of("name", NAME_ATTRIBUTE, "values", VALUES_ATTRIBUTE),
+ null);
+
private MockBuildLanguageSpecProvider specProvider;
@Before
@@ -95,6 +104,33 @@
}
@Test
+ public void testNoErrorsForValidStringDict() {
+ specProvider.setRules(ImmutableMap.of(CONFIG_SETTING.name, CONFIG_SETTING));
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "config_setting(",
+ " name = 'setting',",
+ " values = {'key1', 'value1', 'key2', 'value2'},",
+ ")");
+ assertNoErrors(file);
+ }
+
+ @Test
+ public void testErrorForInvalidDict() {
+ specProvider.setRules(ImmutableMap.of(CONFIG_SETTING.name, CONFIG_SETTING));
+ BuildFile file =
+ createBuildFile(
+ new WorkspacePath("java/com/google/BUILD"),
+ "config_setting(",
+ " name = 'setting',",
+ " values = 1,",
+ ")");
+ assertHasError(
+ file, "Invalid value for attribute 'values'. Expected a value of type 'STRING_DICT'");
+ }
+
+ @Test
public void testGlobTreatedAsList() {
specProvider.setRules(ImmutableMap.of(JAVA_TEST.name, JAVA_TEST));
BuildFile file =
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java
index c1b1f8d..c1008cd 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java
@@ -15,16 +15,15 @@
*/
package com.google.idea.blaze.clwb.run;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.idea.blaze.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.command.buildresult.BuildResultHelper;
import com.google.idea.blaze.base.issueparser.IssueOutputLineProcessor;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.projectview.ProjectViewManager;
@@ -50,7 +49,6 @@
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 {
@@ -109,7 +107,8 @@
final ProjectViewSet projectViewSet =
ProjectViewManager.getInstance(project).getProjectViewSet();
- final List<File> outputArtifacts = Lists.newArrayList();
+ BuildResultHelper buildResultHelper = BuildResultHelper.forFiles(file -> true);
+
final ListenableFuture<Void> buildOperation =
BlazeExecutor.submitTask(
project,
@@ -128,9 +127,8 @@
BlazeCommandName.BUILD)
.addTargets(configuration.getTarget())
.addBlazeFlags(BlazeFlags.buildFlags(project, projectViewSet))
- .addBlazeFlags(handlerState.getBlazeFlags());
-
- command.addBlazeFlags("--experimental_show_artifacts");
+ .addBlazeFlags(handlerState.getBlazeFlags())
+ .addBlazeFlags(buildResultHelper.getBuildFlags());
// 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.
@@ -142,8 +140,7 @@
.addBlazeCommand(command.build())
.context(context)
.stderr(
- LineProcessingOutputStream.of(
- new ExperimentalShowArtifactsLineProcessor(outputArtifacts),
+ buildResultHelper.stderr(
new IssueOutputLineProcessor(project, context, workspaceRoot)))
.build()
.run();
@@ -156,6 +153,7 @@
} catch (InterruptedException | java.util.concurrent.ExecutionException e) {
throw new ExecutionException(e);
}
+ ImmutableList<File> outputArtifacts = buildResultHelper.getBuildArtifacts();
if (outputArtifacts.isEmpty()) {
throw new ExecutionException(
String.format("No output artifacts found when building %s", configuration.getTarget()));
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java b/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java
index 0a48b17..b901eb0 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/producers/BlazeCidrTestConfigurationProducer.java
@@ -17,12 +17,15 @@
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.command.BlazeCommandName;
+import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.run.BlazeCommandRunConfiguration;
import com.google.idea.blaze.base.run.BlazeCommandRunConfigurationType;
+import com.google.idea.blaze.base.run.TestTargetHeuristic;
import com.google.idea.blaze.base.run.producers.BlazeRunConfigurationProducer;
import com.google.idea.blaze.base.run.state.BlazeCommandRunConfigurationCommonState;
import com.google.idea.blaze.base.settings.Blaze;
-import com.google.idea.blaze.clwb.run.test.BlazeCidrTestTarget;
+import com.google.idea.blaze.clwb.run.test.GoogleTestLocation;
+import com.google.idea.blaze.clwb.run.test.GoogleTestSpecification;
import com.intellij.execution.Location;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -60,12 +63,16 @@
if (element == null) {
return false;
}
- BlazeCidrTestTarget testObject = BlazeCidrTestTarget.findTestObject(element);
- if (testObject == null) {
+ GoogleTestLocation test = GoogleTestLocation.findGoogleTest(element);
+ if (test == null) {
return false;
}
- sourceElement.set(testObject.element);
- configuration.setTarget(testObject.label);
+ Label label = getTestTarget(test.getPsiElement());
+ if (label == null) {
+ return false;
+ }
+ sourceElement.set(test.getPsiElement());
+ configuration.setTarget(label);
BlazeCommandRunConfigurationCommonState handlerState =
configuration.getHandlerStateIfType(BlazeCommandRunConfigurationCommonState.class);
if (handlerState == null) {
@@ -74,7 +81,7 @@
handlerState.setCommand(BlazeCommandName.TEST);
ImmutableList.Builder<String> flags = ImmutableList.builder();
- String testFilter = testObject.getTestFilterFlag();
+ String testFilter = test.getTestFilterFlag();
if (testFilter != null) {
flags.add(testFilter);
}
@@ -83,7 +90,8 @@
handlerState.setBlazeFlags(flags.build());
configuration.setName(
String.format(
- "%s test: %s", Blaze.buildSystemName(configuration.getProject()), testObject.name));
+ "%s test: %s",
+ Blaze.buildSystemName(configuration.getProject()), getTestName(label, test.gtest)));
return true;
}
@@ -102,11 +110,27 @@
if (element == null) {
return false;
}
- BlazeCidrTestTarget testObject = BlazeCidrTestTarget.findTestObject(element);
- if (testObject == null) {
+ GoogleTestLocation test = GoogleTestLocation.findGoogleTest(element);
+ if (test == null) {
return false;
}
- return testObject.label.equals(configuration.getTarget())
- && Objects.equals(handlerState.getTestFilterFlag(), testObject.getTestFilterFlag());
+ Label label = getTestTarget(test.getPsiElement());
+ if (label == null) {
+ return false;
+ }
+ return label.equals(configuration.getTarget())
+ && Objects.equals(handlerState.getTestFilterFlag(), test.getTestFilterFlag());
+ }
+
+ @Nullable
+ private static Label getTestTarget(PsiElement element) {
+ return TestTargetHeuristic.testTargetForPsiElement(element);
+ }
+
+ private static String getTestName(Label target, GoogleTestSpecification gtest) {
+ String filterDescription = gtest.description();
+ return filterDescription != null
+ ? String.format("%s (%s)", filterDescription, target.toString())
+ : target.toString();
}
}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestEventsHandler.java b/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestEventsHandler.java
index 831a81b..f117615 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestEventsHandler.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestEventsHandler.java
@@ -22,8 +22,6 @@
import com.intellij.execution.Location;
import com.intellij.execution.testframework.sm.runner.SMTestLocator;
import com.intellij.openapi.project.Project;
-import com.intellij.util.io.URLUtil;
-import com.jetbrains.cidr.execution.testing.OCGoogleTestLocationProvider;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
@@ -39,7 +37,7 @@
@Override
public SMTestLocator getTestLocator() {
- return OCGoogleTestLocationProvider.INSTANCE;
+ return BlazeCppTestLocator.INSTANCE;
}
@Nullable
@@ -47,9 +45,9 @@
public String getTestFilter(Project project, List<Location<?>> testLocations) {
List<String> filters = new ArrayList<>();
for (Location<?> location : testLocations) {
- BlazeCidrTestTarget target = BlazeCidrTestTarget.findTestObject(location.getPsiElement());
- if (target != null && target.testFilter != null) {
- filters.add(target.testFilter);
+ GoogleTestLocation test = GoogleTestLocation.findGoogleTest(location);
+ if (test != null && test.testFilter != null) {
+ filters.add(test.testFilter);
}
}
if (filters.isEmpty()) {
@@ -57,22 +55,4 @@
}
return String.format("%s=%s", BlazeFlags.TEST_FILTER, Joiner.on(':').join(filters));
}
-
- @Override
- public String suiteLocationUrl(@Nullable Kind kind, String name) {
- return OCGoogleTestLocationProvider.PROTOCOL + URLUtil.SCHEME_SEPARATOR + name;
- }
-
- @Override
- public String testLocationUrl(
- @Nullable Kind kind, String parentSuite, String name, @Nullable String className) {
- if (className == null) {
- return OCGoogleTestLocationProvider.PROTOCOL + URLUtil.SCHEME_SEPARATOR + name;
- }
- return OCGoogleTestLocationProvider.PROTOCOL
- + URLUtil.SCHEME_SEPARATOR
- + className
- + "."
- + name;
- }
}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCppTestLocator.java b/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCppTestLocator.java
new file mode 100644
index 0000000..283e78d
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCppTestLocator.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2017 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run.test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.idea.blaze.base.run.smrunner.SmRunnerUtils;
+import com.intellij.execution.Location;
+import com.intellij.execution.testframework.sm.runner.SMTestLocator;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.CommonProcessors;
+import com.jetbrains.cidr.execution.testing.CidrTestUtil;
+import com.jetbrains.cidr.lang.psi.OCMacroCall;
+import com.jetbrains.cidr.lang.psi.OCStruct;
+import com.jetbrains.cidr.lang.symbols.OCSymbol;
+import com.jetbrains.cidr.lang.symbols.cpp.OCStructSymbol;
+import com.jetbrains.cidr.lang.symbols.symtable.OCGlobalProjectSymbolsCache;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.annotation.Nullable;
+
+/** Locate cpp test classes / methods for test UI navigation. */
+public class BlazeCppTestLocator implements SMTestLocator {
+
+ public static final BlazeCppTestLocator INSTANCE = new BlazeCppTestLocator();
+
+ private static final Pattern SUITE_PATTERN = Pattern.compile("((\\w+)/)?(\\w+)(/(\\d+))?");
+ private static final Pattern METHOD_PATTERN = Pattern.compile("(\\w+)(/(\\d+))?");
+
+ private BlazeCppTestLocator() {}
+
+ @Override
+ public List<Location> getLocation(
+ String protocol, String path, Project project, GlobalSearchScope scope) {
+ GoogleTestLocation location = null;
+ if (SmRunnerUtils.GENERIC_SUITE_PROTOCOL.equals(protocol)) {
+ location = getLocation(project, path, null);
+ } else if (SmRunnerUtils.GENERIC_TEST_PROTOCOL.equals(protocol)) {
+ String[] components = path.split(SmRunnerUtils.TEST_NAME_PARTS_SPLITTER);
+ location = components.length != 2 ? null : getLocation(project, components[0], components[1]);
+ }
+ return location != null ? ImmutableList.of(location) : ImmutableList.of();
+ }
+
+ @Nullable
+ private static GoogleTestLocation getLocation(
+ Project project, String suiteComponent, @Nullable String methodComponent) {
+ Matcher matcher = SUITE_PATTERN.matcher(suiteComponent);
+ if (!matcher.matches()) {
+ return null;
+ }
+ String instantiation = matcher.group(2);
+ String suite = matcher.group(3);
+ String method = null;
+ if (methodComponent != null) {
+ matcher = METHOD_PATTERN.matcher(methodComponent);
+ if (!matcher.matches()) {
+ return null;
+ }
+ method = matcher.group(1);
+ }
+ PsiElement psi = findPsiElement(project, instantiation, suite, method);
+ if (psi == null) {
+ return null;
+ }
+ GoogleTestSpecification gtest =
+ new GoogleTestSpecification.FromGtestOutput(suiteComponent, methodComponent);
+ return new GoogleTestLocation(psi, gtest);
+ }
+
+ @Nullable
+ private static PsiElement findPsiElement(
+ Project project,
+ @Nullable String instantiation,
+ @Nullable String suite,
+ @Nullable String method) {
+ if (suite == null) {
+ return null;
+ }
+ OCSymbol<?> symbol;
+ if (method != null) {
+ symbol = CidrTestUtil.findGoogleTestSymbol(project, suite, method);
+ } else if (instantiation != null) {
+ symbol = CidrTestUtil.findGoogleTestInstantiationSymbol(project, suite, instantiation);
+ } else {
+ symbol = findSuiteSymbol(project, suite);
+ }
+ if (symbol == null) {
+ return null;
+ }
+ PsiElement psi = symbol.locateDefinition();
+ while (!(psi instanceof OCStruct || psi instanceof OCMacroCall) && psi != null) {
+ PsiElement prev = psi.getPrevSibling();
+ psi = prev == null ? psi.getParent() : prev;
+ }
+ return psi;
+ }
+
+ @Nullable
+ private static OCStructSymbol findSuiteSymbol(Project project, String suite) {
+ CommonProcessors.FindProcessor<OCSymbol> processor =
+ new CommonProcessors.FindProcessor<OCSymbol>() {
+ @Override
+ protected boolean accept(OCSymbol symbol) {
+ return symbol instanceof OCStructSymbol
+ && CidrTestUtil.isGoogleTestClass((OCStructSymbol) symbol);
+ }
+ };
+ OCGlobalProjectSymbolsCache.processTopLevelAndMemberSymbols(project, processor, suite);
+ if (processor.isFound()) {
+ return (OCStructSymbol) processor.getFoundValue();
+ }
+ Collection<OCStructSymbol> symbolsForSuite =
+ CidrTestUtil.findGoogleTestSymbolsForSuiteSorted(project, suite);
+ return Iterables.getFirst(symbolsForSuite, null);
+ }
+}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestTarget.java b/clwb/src/com/google/idea/blaze/clwb/run/test/GoogleTestLocation.java
similarity index 76%
rename from clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestTarget.java
rename to clwb/src/com/google/idea/blaze/clwb/run/test/GoogleTestLocation.java
index acf3966..ebf41c1 100644
--- a/clwb/src/com/google/idea/blaze/clwb/run/test/BlazeCidrTestTarget.java
+++ b/clwb/src/com/google/idea/blaze/clwb/run/test/GoogleTestLocation.java
@@ -16,8 +16,8 @@
package com.google.idea.blaze.clwb.run.test;
import com.google.idea.blaze.base.command.BlazeFlags;
-import com.google.idea.blaze.base.model.primitives.Label;
-import com.google.idea.blaze.base.run.TestTargetHeuristic;
+import com.intellij.execution.Location;
+import com.intellij.execution.PsiLocation;
import com.intellij.openapi.util.Couple;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
@@ -35,23 +35,16 @@
import java.util.List;
import javax.annotation.Nullable;
-/** A blaze cpp test target, together with optional test filter. */
-public class BlazeCidrTestTarget {
+/** A {@link PsiLocation} with corresponding gtest specification */
+public class GoogleTestLocation extends PsiLocation<PsiElement> {
- public final PsiElement element;
- public final Label label;
+ public final GoogleTestSpecification gtest;
@Nullable public final String testFilter;
- public final String name;
- private BlazeCidrTestTarget(PsiElement element, Label label, @Nullable String testFilter) {
- this.element = element;
- this.label = label;
- this.testFilter = testFilter;
- if (testFilter != null) {
- name = String.format("%s (%s)", testFilter, label.toString());
- } else {
- name = label.toString();
- }
+ GoogleTestLocation(PsiElement psi, GoogleTestSpecification gtest) {
+ super(psi);
+ this.gtest = gtest;
+ this.testFilter = gtest.testFilter();
}
/** The raw test filter string with '--test_filter=' prepended, or null if there is no filter. */
@@ -61,35 +54,15 @@
}
@Nullable
- private static BlazeCidrTestTarget createFromFile(@Nullable PsiElement element) {
- return createFromClassAndMethod(element, null, null);
- }
-
- @Nullable
- private static BlazeCidrTestTarget createFromClass(
- @Nullable PsiElement element, String className) {
- return createFromClassAndMethod(element, className, null);
- }
-
- @Nullable
- private static BlazeCidrTestTarget createFromClassAndMethod(
- @Nullable PsiElement element, String classOrSuiteName, @Nullable String testName) {
- Label label = TestTargetHeuristic.testTargetForPsiElement(element);
- if (label == null) {
- return null;
+ public static GoogleTestLocation findGoogleTest(Location<?> location) {
+ if (location instanceof GoogleTestLocation) {
+ return (GoogleTestLocation) location;
}
- String filter = null;
- if (classOrSuiteName != null) {
- filter = classOrSuiteName;
- if (testName != null) {
- filter += "." + testName;
- }
- }
- return new BlazeCidrTestTarget(element, label, filter);
+ return findGoogleTest(location.getPsiElement());
}
@Nullable
- public static BlazeCidrTestTarget findTestObject(PsiElement element) {
+ public static GoogleTestLocation findGoogleTest(PsiElement element) {
// Copied from on CidrGoogleTestRunConfigurationProducer::findTestObject.
// Precedence order (decreasing): class/function, macro, file
PsiElement parent =
@@ -118,8 +91,7 @@
if (name != null) {
return createFromClassAndMethod(struct, name.first, name.second);
}
- return createFromClass(
- struct, ((OCStructSymbol) owner).getQualifiedName().getName());
+ return createFromClass(struct, ((OCStructSymbol) owner).getQualifiedName().getName());
}
}
}
@@ -146,8 +118,7 @@
CidrTestUtil.findGoogleTestSymbol(element.getProject(), suiteName, testName);
if (symbol != null) {
OCStruct targetElement = (OCStruct) symbol.locateDefinition();
- return createFromClassAndMethod(
- targetElement, suiteName, isSuite ? null : testName);
+ return createFromClassAndMethod(targetElement, suiteName, isSuite ? null : testName);
}
}
}
@@ -158,7 +129,9 @@
element.getProject(), suite.first, true);
if (res.size() != 0) {
OCStruct struct = (OCStruct) res.iterator().next().locateDefinition();
- return createFromClassAndMethod(struct, suite.first, null);
+ GoogleTestSpecification gtest =
+ new GoogleTestSpecification.FromPsiElement(suite.first, null, suite.second, null);
+ return new GoogleTestLocation(struct, gtest);
}
}
} else if (parent instanceof OCFile) {
@@ -175,4 +148,26 @@
}
return false;
}
+
+ @Nullable
+ private static GoogleTestLocation createFromFile(@Nullable PsiElement element) {
+ return createFromClassAndMethod(element, null, null);
+ }
+
+ @Nullable
+ private static GoogleTestLocation createFromClass(
+ @Nullable PsiElement element, @Nullable String className) {
+ return createFromClassAndMethod(element, className, null);
+ }
+
+ @Nullable
+ private static GoogleTestLocation createFromClassAndMethod(
+ @Nullable PsiElement element, @Nullable String classOrSuiteName, @Nullable String testName) {
+ if (element == null) {
+ return null;
+ }
+ GoogleTestSpecification gtest =
+ new GoogleTestSpecification.FromPsiElement(classOrSuiteName, testName, null, null);
+ return new GoogleTestLocation(element, gtest);
+ }
}
diff --git a/clwb/src/com/google/idea/blaze/clwb/run/test/GoogleTestSpecification.java b/clwb/src/com/google/idea/blaze/clwb/run/test/GoogleTestSpecification.java
new file mode 100644
index 0000000..2111410
--- /dev/null
+++ b/clwb/src/com/google/idea/blaze/clwb/run/test/GoogleTestSpecification.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2017 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.idea.blaze.clwb.run.test;
+
+import com.google.common.base.Joiner;
+import com.intellij.openapi.util.text.StringUtil;
+import javax.annotation.Nullable;
+
+/** A single gtest test case specification (https://github.com/google/googletest). */
+public interface GoogleTestSpecification {
+
+ /** The gtest filter string. Returns null if there is no filtering. */
+ @Nullable
+ String testFilter();
+
+ /** A human-readable description for this test. Returns null if there is no filtering. */
+ @Nullable
+ String description();
+
+ /**
+ * Built from the raw gtest output, without separating parameter components, etc.<br>
+ * This means there is no ambiguity -- guaranteed to be exactly what the gtest runner expects for
+ * this test case.
+ */
+ class FromGtestOutput implements GoogleTestSpecification {
+
+ private final String suiteComponent;
+ @Nullable private final String methodComponent;
+
+ public FromGtestOutput(String suiteComponent, @Nullable String methodComponent) {
+ this.suiteComponent = suiteComponent;
+ this.methodComponent = methodComponent;
+ }
+
+ @Override
+ public String testFilter() {
+ String method = methodComponent != null ? methodComponent : "*";
+ return String.format("%s.%s", suiteComponent, method);
+ }
+
+ @Override
+ public String description() {
+ return methodComponent == null
+ ? suiteComponent
+ : String.format("%s.%s", suiteComponent, methodComponent);
+ }
+ }
+
+ /**
+ * We don't know whether it's parameterized / typed in this context, so need to provide a more
+ * flexible filter.
+ */
+ class FromPsiElement implements GoogleTestSpecification {
+ @Nullable private final String suiteOrClass;
+ @Nullable private final String method;
+ @Nullable private final String instantiation;
+ @Nullable private final String param;
+
+ public FromPsiElement(
+ @Nullable String suiteOrClass,
+ @Nullable String method,
+ @Nullable String instantiation,
+ @Nullable String param) {
+ this.suiteOrClass = suiteOrClass;
+ this.method = method;
+ this.instantiation = instantiation;
+ this.param = param;
+ }
+
+ @Override
+ @Nullable
+ public String testFilter() {
+ if (suiteOrClass == null) {
+ return null;
+ }
+ String method = StringUtil.notNullize(this.method, "*");
+ String param = StringUtil.notNullize(this.param, "*");
+ if (instantiation != null) {
+ return Joiner.on(':')
+ .join(
+ String.format("%s/%s.%s/%s", instantiation, suiteOrClass, method, param),
+ String.format("%s/%s/%s.%s", instantiation, suiteOrClass, param, method));
+ }
+ // we don't know whether it's parameterized and/or typed, so need to handle all cases
+ return Joiner.on(':')
+ .join(
+ String.format("%s.%s", suiteOrClass, method),
+ String.format("%s/%s.%s", suiteOrClass, param, method),
+ String.format("*/%s.%s/*", suiteOrClass, method),
+ String.format("*/%s/*.%s", suiteOrClass, method));
+ }
+
+ @Override
+ @Nullable
+ public String description() {
+ if (suiteOrClass == null) {
+ return null;
+ }
+ if (method == null) {
+ return suiteOrClass;
+ }
+ if (instantiation == null) {
+ return suiteOrClass + "." + method;
+ }
+ String param = StringUtil.notNullize(this.param, "*");
+ return String.format("%s/%s.%s/%s", instantiation, suiteOrClass, method, param);
+ }
+ }
+}
diff --git a/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java b/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
index f4b5cd6..2fea837 100644
--- a/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
+++ b/cpp/src/com/google/idea/blaze/cpp/BlazeConfigurationResolver.java
@@ -54,6 +54,7 @@
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -371,7 +372,7 @@
// If a source file is in two different targets,
// 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()));
+ targetsForSourceFile.sort(Comparator.comparing(TargetKey::toString));
TargetKey targetKey = Iterables.getFirst(targetsForSourceFile, null);
assert (targetKey != null);
diff --git a/intellij_platform_sdk/build_defs.bzl b/intellij_platform_sdk/build_defs.bzl
index f833101..357308a 100644
--- a/intellij_platform_sdk/build_defs.bzl
+++ b/intellij_platform_sdk/build_defs.bzl
@@ -4,8 +4,8 @@
INDIRECT_IJ_PRODUCTS = {
"intellij-latest": "intellij-2016.3.1",
"android-studio-latest": "android-studio-145.1617.8",
- "android-studio-beta": "android-studio-2.3.0.4",
- "clion-latest": "clion-162.1967.7",
+ "android-studio-beta": "android-studio-2.3.0.6",
+ "clion-latest": "clion-2016.3.2",
}
DIRECT_IJ_PRODUCTS = {
@@ -21,10 +21,6 @@
ide="android-studio",
directory="AI_145_1617_8",
),
- "android-studio-2.3.0.3": struct(
- ide="android-studio",
- directory="android_studio_2_3_0_3",
- ),
"android-studio-2.3.0.4": struct(
ide="android-studio",
directory="android_studio_2_3_0_4",
diff --git a/java/src/com/google/idea/blaze/java/wizard2/BlazeEditProjectViewImportWizardStep.java b/java/src/com/google/idea/blaze/java/wizard2/BlazeEditProjectViewImportWizardStep.java
index 4a6bc6a..3d57300 100644
--- a/java/src/com/google/idea/blaze/java/wizard2/BlazeEditProjectViewImportWizardStep.java
+++ b/java/src/com/google/idea/blaze/java/wizard2/BlazeEditProjectViewImportWizardStep.java
@@ -83,6 +83,7 @@
public void onWizardFinished() throws CommitStepException {
try {
getProjectBuilder().commit();
+ control.commit();
} catch (BlazeProjectCommitException e) {
throw new CommitStepException(e.getMessage());
}
diff --git a/proto/proto_deps.jar b/proto/proto_deps.jar
index ac441be..b2e5390 100755
--- a/proto/proto_deps.jar
+++ b/proto/proto_deps.jar
Binary files differ
diff --git a/version.bzl b/version.bzl
index f56966e..5e34b4b 100644
--- a/version.bzl
+++ b/version.bzl
@@ -1,3 +1,3 @@
"""Version of the blaze plugin."""
-VERSION = "2017.02.13.1"
+VERSION = "2017.02.27.1"