From 47ddb954bd0075ec0db0e9b4944e9669594a61bd Mon Sep 17 00:00:00 2001 From: Chris Hegarty Date: Tue, 10 May 2016 13:34:30 +0100 Subject: [PATCH] 8074716: IntelliJ IDEA project support Co-authored-by: Maurizio Cimadamore Reviewed-by: rriggs --- .hgignore | 1 + common/bin/idea.sh | 199 ++++++++++ make/idea/idea.gmk | 39 ++ make/idea/template/.name | 1 + make/idea/template/ant.xml | 16 + make/idea/template/build.xml | 126 ++++++ make/idea/template/compiler.xml | 35 ++ .../template/copyright/profiles_settings.xml | 3 + make/idea/template/jdk.iml | 22 ++ make/idea/template/misc.xml | 9 + make/idea/template/modules.xml | 9 + make/idea/template/scopes/scope_settings.xml | 5 + .../template/src/idea/JdkIdeaAntLogger.java | 373 ++++++++++++++++++ make/idea/template/vcs.xml | 14 + make/idea/template/workspace.xml | 77 ++++ test/make/TestIdea.gmk | 46 +++ test/make/TestMake.gmk | 7 +- 17 files changed, 980 insertions(+), 2 deletions(-) create mode 100644 common/bin/idea.sh create mode 100644 make/idea/idea.gmk create mode 100644 make/idea/template/.name create mode 100644 make/idea/template/ant.xml create mode 100644 make/idea/template/build.xml create mode 100644 make/idea/template/compiler.xml create mode 100644 make/idea/template/copyright/profiles_settings.xml create mode 100644 make/idea/template/jdk.iml create mode 100644 make/idea/template/misc.xml create mode 100644 make/idea/template/modules.xml create mode 100644 make/idea/template/scopes/scope_settings.xml create mode 100644 make/idea/template/src/idea/JdkIdeaAntLogger.java create mode 100644 make/idea/template/vcs.xml create mode 100644 make/idea/template/workspace.xml create mode 100644 test/make/TestIdea.gmk diff --git a/.hgignore b/.hgignore index aec0e31d13..9aab81ce35 100644 --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,6 @@ ^build/ ^dist/ +^.idea/ nbproject/private/ ^webrev ^.hgtip diff --git a/common/bin/idea.sh b/common/bin/idea.sh new file mode 100644 index 0000000000..911d309c07 --- /dev/null +++ b/common/bin/idea.sh @@ -0,0 +1,199 @@ +#!/bin/sh +# +# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# Shell script for generating an IDEA project from a given list of modules + +usage() { + echo "usage: $0 [-h|--help] [-v|--verbose] [-o|--output ] [modules]+" + exit 1 +} + +SCRIPT_DIR=`dirname $0` +PWD=`pwd` +cd $SCRIPT_DIR; SCRIPT_DIR=`pwd` +cd ../../; TOP=`pwd`; cd $PWD + +IDEA_OUTPUT=$TOP/.idea +VERBOSE="false" +while [ $# -gt 0 ] +do + case $1 in + -h | --help ) + usage + ;; + + -v | --vebose ) + VERBOSE="true" + ;; + + -o | --output ) + IDEA_OUTPUT=$2 + shift + ;; + + -*) # bad option + usage + ;; + + * ) # non option + break + ;; + esac + shift +done + +mkdir $IDEA_OUTPUT || exit 1 +cd $IDEA_OUTPUT; IDEA_OUTPUT=`pwd` + +IDEA_MAKE="$TOP/make/idea" +IDEA_TEMPLATE="$IDEA_MAKE/template" +IML_TEMPLATE="$IDEA_TEMPLATE/jdk.iml" +ANT_TEMPLATE="$IDEA_TEMPLATE/ant.xml" +IDEA_IML="$IDEA_OUTPUT/jdk.iml" +IDEA_ANT="$IDEA_OUTPUT/ant.xml" + +if [ "$VERBOSE" = "true" ] ; then + echo "output dir: $IDEA_OUTPUT" + echo "idea template dir: $IDEA_TEMPLATE" +fi + +if [ ! -f "$IML_TEMPLATE" ] ; then + echo "FATAL: cannot find $IML_TEMPLATE" >&2; exit 1 +fi + +if [ ! -f "$ANT_TEMPLATE" ] ; then + echo "FATAL: cannot find $ANT_TEMPLATE" >&2; exit 1 +fi + +cp -r "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT" +cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I make/common idea MAKEOVERRIDES= OUT=$IDEA_OUTPUT/env.cfg MODULES="$*" || exit 1 +cd $SCRIPT_DIR + +. $IDEA_OUTPUT/env.cfg + +# Expect MODULE_ROOTS, MODULE_NAMES, BOOT_JDK & SPEC to be set +if [ "x$MODULE_ROOTS" = "x" ] ; then + echo "FATAL: MODULE_ROOTS is empty" >&2; exit 1 +fi + +if [ "x$MODULE_NAMES" = "x" ] ; then + echo "FATAL: MODULE_NAMES is empty" >&2; exit 1 +fi + +if [ "x$BOOT_JDK" = "x" ] ; then + echo "FATAL: BOOT_JDK is empty" >&2; exit 1 +fi + +if [ "x$SPEC" = "x" ] ; then + echo "FATAL: SPEC is empty" >&2; exit 1 +fi + +SOURCE_FOLDER=" " +SOURCE_FOLDERS_DONE="false" + +addSourceFolder() { + root=$@ + relativePath="`echo "$root" | sed -e s@"$TOP/\(.*$\)"@"\1"@`" + folder="`echo "$SOURCE_FOLDER" | sed -e s@"\(.*/\)####\(.*\)"@"\1$relativePath\2"@`" + printf "%s\n" "$folder" >> $IDEA_IML +} + +### Generate project iml +RELATIVE_BUILD_DIR="`dirname $SPEC | sed -e s@"$TOP/\(.*$\)"@"\1"@`" +rm -f $IDEA_IML +while IFS= read -r line +do + if echo "$line" | egrep "^ .* /dev/null ; then + if [ "$SOURCE_FOLDERS_DONE" = "false" ] ; then + SOURCE_FOLDERS_DONE="true" + for root in $MODULE_ROOTS; do + addSourceFolder $root + done + fi + elif echo "$line" | egrep "^ .* /dev/null ; then + ul="`echo "$line" | sed -e s@"\(.*/\)####\(.*\)"@"\1$RELATIVE_BUILD_DIR\2"@`" + printf "%s\n" "$ul" >> $IDEA_IML + else + printf "%s\n" "$line" >> $IDEA_IML + fi +done < "$IML_TEMPLATE" + + +MODULE_NAME=" " + +addModuleName() { + mn="`echo "$MODULE_NAME" | sed -e s@"\(.*\)####\(.*\)"@"\1$MODULE_NAMES\2"@`" + printf "%s\n" "$mn" >> $IDEA_ANT +} + +BUILD_DIR=" " + +addBuildDir() { + DIR=`dirname $SPEC` + mn="`echo "$BUILD_DIR" | sed -e s@"\(.*\)####\(.*\)"@"\1$DIR\2"@`" + printf "%s\n" "$mn" >> $IDEA_ANT +} + +### Generate ant.xml + +rm -f $IDEA_ANT +while IFS= read -r line +do + if echo "$line" | egrep "^ .* /dev/null ; then + addModuleName + elif echo "$line" | egrep "^ .* /dev/null ; then + addBuildDir + else + printf "%s\n" "$line" >> $IDEA_ANT + fi +done < "$ANT_TEMPLATE" + +### Compile the custom Logger + +CLASSES=$IDEA_OUTPUT/classes + +if [ "x$ANT_HOME" = "x" ] ; then + # try some common locations, before giving up + if [ -f "/usr/share/ant/lib/ant.jar" ] ; then + ANT_HOME="/usr/share/ant" + elif [ -f "/usr/local/Cellar/ant/1.9.4/libexec/lib/ant.jar" ] ; then + ANT_HOME="/usr/local/Cellar/ant/1.9.4/libexec" + else + echo "FATAL: cannot find ant. Try setting ANT_HOME." >&2; exit 1 + fi +fi +CP=$ANT_HOME/lib/ant.jar +rm -rf $CLASSES; mkdir $CLASSES + +if [ "x$CYGPATH" = "x" ] ; then ## CYGPATH may be set in env.cfg + JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/JdkIdeaAntLogger.java + JAVAC_CLASSES=$CLASSES + JAVAC_CP=$CP +else + JAVAC_SOURCE_FILE=`cygpath -am $IDEA_OUTPUT/src/idea/JdkIdeaAntLogger.java` + JAVAC_CLASSES=`cygpath -am $CLASSES` + JAVAC_CP=`cygpath -am $CP` +fi + +$BOOT_JDK/bin/javac -d $JAVAC_CLASSES -cp $JAVAC_CP $JAVAC_SOURCE_FILE diff --git a/make/idea/idea.gmk b/make/idea/idea.gmk new file mode 100644 index 0000000000..329c01cd5e --- /dev/null +++ b/make/idea/idea.gmk @@ -0,0 +1,39 @@ +include Makefile +include make/MainSupport.gmk + +.PHONY: idea + +ifeq ($(SPEC),) + ifneq ($(words $(SPECS)),1) + @echo "Error: Multiple build specification files found. Please select one explicitly." + @exit 2 + endif + idea: + @cd $(topdir) + @$(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/idea/idea.gmk SPEC=$(SPECS) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) MODULES="$(MODULES)" idea +else #with SPEC + include make/common/Modules.gmk + + ifeq ($(MODULES),) + SEL_MODULES := $(call FindAllModules) + else + SEL_MODULES := $(MODULES) + endif + + # Find all source dirs for a particular module + # $1 - Module to find source dirs for + FindIdeaModuleSrcDirs = \ + $(strip $(addsuffix /$(strip $1), $(GENERATED_SRC_DIRS) $(IMPORT_MODULES_SRC)) \ + $(wildcard $(foreach sub, $(SRC_SUBDIRS), $(addsuffix /$(strip $1)/$(sub), $(TOP_SRC_DIRS))))) + + + idea: + $(ECHO) "SUPPORT=$(SUPPORT_OUTPUTDIR)" >> $(OUT) + $(ECHO) "MODULE_ROOTS=\"$(foreach mod, $(SEL_MODULES), $(call FindIdeaModuleSrcDirs,$(mod)))\"" >> $(OUT) + $(ECHO) "MODULE_NAMES=\"$(strip $(foreach mod, $(SEL_MODULES), $(mod)))\"" >> $(OUT) + $(ECHO) "SEL_MODULES=\"$(SEL_MODULES)\"" >> $(OUT) + $(ECHO) "BOOT_JDK=\"$(BOOT_JDK)\"" >> $(OUT) + $(ECHO) "CYGPATH=\"$(CYGPATH)\"" >> $(OUT) + $(ECHO) "SPEC=\"$(SPEC)\"" >> $(OUT) + +endif diff --git a/make/idea/template/.name b/make/idea/template/.name new file mode 100644 index 0000000000..b483568579 --- /dev/null +++ b/make/idea/template/.name @@ -0,0 +1 @@ +jdk diff --git a/make/idea/template/ant.xml b/make/idea/template/ant.xml new file mode 100644 index 0000000000..6e72e478cb --- /dev/null +++ b/make/idea/template/ant.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/make/idea/template/build.xml b/make/idea/template/build.xml new file mode 100644 index 0000000000..ed62f29672 --- /dev/null +++ b/make/idea/template/build.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/make/idea/template/compiler.xml b/make/idea/template/compiler.xml new file mode 100644 index 0000000000..f801895e7f --- /dev/null +++ b/make/idea/template/compiler.xml @@ -0,0 +1,35 @@ + + + + + \ No newline at end of file diff --git a/make/idea/template/copyright/profiles_settings.xml b/make/idea/template/copyright/profiles_settings.xml new file mode 100644 index 0000000000..7d61b5cdf1 --- /dev/null +++ b/make/idea/template/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + diff --git a/make/idea/template/jdk.iml b/make/idea/template/jdk.iml new file mode 100644 index 0000000000..5e1436c949 --- /dev/null +++ b/make/idea/template/jdk.iml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/make/idea/template/misc.xml b/make/idea/template/misc.xml new file mode 100644 index 0000000000..e5caa22e0d --- /dev/null +++ b/make/idea/template/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/make/idea/template/modules.xml b/make/idea/template/modules.xml new file mode 100644 index 0000000000..2d8401d039 --- /dev/null +++ b/make/idea/template/modules.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/make/idea/template/scopes/scope_settings.xml b/make/idea/template/scopes/scope_settings.xml new file mode 100644 index 0000000000..db1b8ba446 --- /dev/null +++ b/make/idea/template/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + diff --git a/make/idea/template/src/idea/JdkIdeaAntLogger.java b/make/idea/template/src/idea/JdkIdeaAntLogger.java new file mode 100644 index 0000000000..9913499e7a --- /dev/null +++ b/make/idea/template/src/idea/JdkIdeaAntLogger.java @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package idea; + +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.DefaultLogger; +import org.apache.tools.ant.Project; + +import java.util.EnumSet; +import java.util.Stack; + +import static org.apache.tools.ant.Project.*; + +/** + * This class is used to wrap the IntelliJ ant logger in order to provide more meaningful + * output when building langtools. The basic ant output in IntelliJ can be quite cumbersome to + * work with, as it provides two separate views: (i) a tree view, which is good to display build task + * in a hierarchical fashion as they are processed; and a (ii) plain text view, which gives you + * the full ant output. The main problem is that javac-related messages are buried into the + * ant output (which is made very verbose by IntelliJ in order to support the tree view). It is + * not easy to figure out which node to expand in order to see the error message; switching + * to plain text doesn't help either, as now the output is totally flat. + * + * This logger class removes a lot of verbosity from the IntelliJ ant logger by not propagating + * all the events to the IntelliJ's logger. In addition, certain events are handled in a custom + * fashion, to generate better output during the build. + */ +public final class JdkIdeaAntLogger extends DefaultLogger { + + /** + * This is just a way to pass in customized binary string predicates; + * + * TODO: replace with @code{BiPredicate} and method reference when moving to 8 + */ + enum StringBinaryPredicate { + CONTAINS() { + @Override + boolean apply(String s1, String s2) { + return s1.contains(s2); + } + }, + STARTS_WITH { + @Override + boolean apply(String s1, String s2) { + return s1.startsWith(s2); + } + }, + MATCHES { + @Override + boolean apply(String s1, String s2) { + return s1.matches(s2); + } + }; + + abstract boolean apply(String s1, String s2); + } + + /** + * Various kinds of ant messages that we shall intercept + */ + enum MessageKind { + + /** a make error */ + MAKE_ERROR(StringBinaryPredicate.CONTAINS, MSG_ERR, "error:", "compiler.err"), + /** a make warning */ + MAKE_WARNING(StringBinaryPredicate.CONTAINS, MSG_WARN, "warning:", "compiler.warn"), + /** a make note */ + MAKE_NOTE(StringBinaryPredicate.CONTAINS, MSG_INFO, "note:", "compiler.note"), + /** std make output */ + MAKE_OTHER(StringBinaryPredicate.MATCHES, MSG_INFO, ".*"), + /** a javac crash */ + JAVAC_CRASH(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "An exception has occurred in the compiler"), + /** jtreg test success */ + JTREG_TEST_PASSED(StringBinaryPredicate.STARTS_WITH, MSG_INFO, "Passed: "), + /** jtreg test failure */ + JTREG_TEST_FAILED(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "FAILED: "), + /** jtreg test error */ + JTREG_TEST_ERROR(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "Error: "); + + StringBinaryPredicate sbp; + int priority; + String[] keys; + + MessageKind(StringBinaryPredicate sbp, int priority, String... keys) { + this.sbp = sbp; + this.priority = priority; + this.keys = keys; + } + + /** + * Does a given message string matches this kind? + */ + boolean matches(String s) { + for (String key : keys) { + if (sbp.apply(s, key)) { + return true; + } + } + return false; + } + } + + /** + * This enum is used to represent the list of tasks we need to keep track of during logging. + */ + enum Task { + /** javac task - invoked during compilation */ + MAKE("exec", MessageKind.MAKE_ERROR, MessageKind.MAKE_WARNING, MessageKind.MAKE_NOTE, + MessageKind.MAKE_OTHER, MessageKind.JAVAC_CRASH), + /** jtreg task - invoked during test execution */ + JTREG("jtreg", MessageKind.JTREG_TEST_PASSED, MessageKind.JTREG_TEST_FAILED, MessageKind.JTREG_TEST_ERROR), + /** initial synthetic task when the logger is created */ + ROOT("") { + @Override + boolean matches(String s) { + return false; + } + }, + /** synthetic task catching any other tasks not in this list */ + ANY("") { + @Override + boolean matches(String s) { + return true; + } + }; + + String taskName; + MessageKind[] msgs; + + Task(String taskName, MessageKind... msgs) { + this.taskName = taskName; + this.msgs = msgs; + } + + boolean matches(String s) { + return s.equals(taskName); + } + } + + /** + * This enum is used to represent the list of targets we need to keep track of during logging. + * A regular expression is used to match a given target name. + */ + enum Target { + /** jtreg target - executed when launching tests */ + JTREG("jtreg") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Running jtreg tests: " + e.getProject().getProperty("jtreg.tests"); + } + }, + /** build selected modules */ + BUILD_MODULE("build-module") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Building modules: " + e.getProject().getProperty("module.name") + "..."; + } + }, + /** build images */ + BUILD_IMAGES("images") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Building images..."; + } + }, + /** build images */ + CONFIGURE("-do-configure") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Configuring build..."; + } + }, + /** synthetic target catching any other target not in this list */ + ANY("") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Executing Ant target(s): " + e.getProject().getProperty("ant.project.invoked-targets"); + } + @Override + boolean matches(String msg) { + return true; + } + }; + + String targetRegex; + + Target(String targetRegex) { + this.targetRegex = targetRegex; + } + + boolean matches(String msg) { + return msg.matches(targetRegex); + } + + abstract String getDisplayMessage(BuildEvent e); + } + + /** + * A custom build event used to represent status changes which should be notified inside + * Intellij + */ + static class StatusEvent extends BuildEvent { + + /** the target to which the status update refers */ + Target target; + + StatusEvent(BuildEvent e, Target target) { + super(new StatusTask(e, target.getDisplayMessage(e))); + this.target = target; + setMessage(getTask().getTaskName(), 2); + } + + /** + * A custom task used to channel info regarding a status change + */ + static class StatusTask extends org.apache.tools.ant.Task { + StatusTask(BuildEvent event, String msg) { + setProject(event.getProject()); + setOwningTarget(event.getTarget()); + setTaskName(msg); + } + } + } + + /** wrapped ant logger (IntelliJ's own logger) */ + DefaultLogger logger; + + /** flag - is this the first target we encounter? */ + boolean firstTarget = true; + + /** flag - should subsequenet failures be suppressed ? */ + boolean suppressTaskFailures = false; + + /** flag - have we ran into a javac crash ? */ + boolean crashFound = false; + + /** stack of status changes associated with pending targets */ + Stack statusEvents = new Stack<>(); + + /** stack of pending tasks */ + Stack tasks = new Stack<>(); + + public JdkIdeaAntLogger(Project project) { + for (Object o : project.getBuildListeners()) { + if (o instanceof DefaultLogger) { + this.logger = (DefaultLogger)o; + project.removeBuildListener((BuildListener)o); + project.addBuildListener(this); + } + } + tasks.push(Task.ROOT); + } + + @Override + public void buildStarted(BuildEvent event) { + //do nothing + } + + @Override + public void buildFinished(BuildEvent event) { + //do nothing + } + + @Override + public void targetStarted(BuildEvent event) { + EnumSet statusKinds = firstTarget ? + EnumSet.allOf(Target.class) : + EnumSet.complementOf(EnumSet.of(Target.ANY)); + + String targetName = event.getTarget().getName(); + + for (Target statusKind : statusKinds) { + if (statusKind.matches(targetName)) { + StatusEvent statusEvent = new StatusEvent(event, statusKind); + statusEvents.push(statusEvent); + logger.taskStarted(statusEvent); + firstTarget = false; + return; + } + } + } + + @Override + public void targetFinished(BuildEvent event) { + if (!statusEvents.isEmpty()) { + StatusEvent lastEvent = statusEvents.pop(); + if (lastEvent.target.matches(event.getTarget().getName())) { + logger.taskFinished(lastEvent); + } + } + } + + @Override + public void taskStarted(BuildEvent event) { + String taskName = event.getTask().getTaskName(); + System.err.println("task started " + taskName); + for (Task task : Task.values()) { + if (task.matches(taskName)) { + tasks.push(task); + return; + } + } + } + + @Override + public void taskFinished(BuildEvent event) { + if (tasks.peek() == Task.ROOT) { + //we need to 'close' the root task to get nicer output + logger.taskFinished(event); + } else if (!suppressTaskFailures && event.getException() != null) { + //the first (innermost) task failure should always be logged + event.setMessage(event.getException().toString(), 0); + event.setException(null); + //note: we turn this into a plain message to avoid stack trace being logged by Idea + logger.messageLogged(event); + suppressTaskFailures = true; + } + tasks.pop(); + } + + @Override + public void messageLogged(BuildEvent event) { + String msg = event.getMessage(); + + boolean processed = false; + + if (!tasks.isEmpty()) { + Task task = tasks.peek(); + for (MessageKind messageKind : task.msgs) { + if (messageKind.matches(msg)) { + event.setMessage(msg, messageKind.priority); + processed = true; + if (messageKind == MessageKind.JAVAC_CRASH) { + crashFound = true; + } + break; + } + } + } + + if (event.getPriority() == MSG_ERR || crashFound) { + //we log errors regardless of owning task + logger.messageLogged(event); + suppressTaskFailures = true; + } else if (processed) { + logger.messageLogged(event); + } + } +} diff --git a/make/idea/template/vcs.xml b/make/idea/template/vcs.xml new file mode 100644 index 0000000000..876d3cd2ef --- /dev/null +++ b/make/idea/template/vcs.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/make/idea/template/workspace.xml b/make/idea/template/workspace.xml new file mode 100644 index 0000000000..2423c3d41f --- /dev/null +++ b/make/idea/template/workspace.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/make/TestIdea.gmk b/test/make/TestIdea.gmk new file mode 100644 index 0000000000..39d93c5cda --- /dev/null +++ b/test/make/TestIdea.gmk @@ -0,0 +1,46 @@ + +# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include $(SPEC) +include MakeBase.gmk + +default: all + +IDEA_OUTPUT_DIR := $(TESTMAKE_OUTPUTDIR)/verify-idea + +clean-idea: + $(RM) -r $(IDEA_OUTPUT_DIR) + +verify-idea: + $(MKDIR) -p $(IDEA_OUTPUT_DIR) + $(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea1 + $(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea2 java.base + $(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea3 java.base jdk.compiler + +TEST_TARGETS += verify-idea + +all: $(TEST_TARGETS) + +.PHONY: default all verify-idea diff --git a/test/make/TestMake.gmk b/test/make/TestMake.gmk index 1f33e1786a..f3676a0015 100644 --- a/test/make/TestMake.gmk +++ b/test/make/TestMake.gmk @@ -33,7 +33,10 @@ make-base: java-compilation: +$(MAKE) -f TestJavaCompilation.gmk $(TEST_SUBTARGET) +test-idea: + +$(MAKE) -f TestIdea.gmk $(TEST_SUBTARGET) -all: make-base java-compilation -.PHONY: default all make-base java-compilation +all: make-base java-compilation test-idea + +.PHONY: default all make-base java-compilation test-idea