Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alexander Lobas
2012-04-28 18:34:28 +04:00
39 changed files with 407 additions and 145 deletions
@@ -48,6 +48,7 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider<CompileStepBefor
private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.options.CompileStepBeforeRun");
public static final Key<MakeBeforeRunTask> ID = Key.create("Make");
private static final Key<RunConfiguration> RUN_CONFIGURATION = Key.create("RUN_CONFIGURATION");
private static final Key<String> RUN_CONFIGURATION_TYPE_ID = Key.create("RUN_CONFIGURATION_TYPE_ID");
@NonNls protected static final String MAKE_PROJECT_ON_RUN_KEY = "makeProjectOnRun";
@@ -148,6 +149,7 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider<CompileStepBefor
if (!myProject.isDisposed()) {
done.down();
scope.putUserData(RUN_CONFIGURATION, configuration);
scope.putUserData(RUN_CONFIGURATION_TYPE_ID, configuration.getType().getId());
compilerManager.make(scope, callback);
}
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.components.JBList;
@@ -59,6 +60,7 @@ public class CodeStyleGenerationConfigurable implements Configurable {
public CodeStyleGenerationConfigurable(CodeStyleSettings settings) {
mySettings = settings;
myMembersOrderList = new MembersOrderList();
myPanel.setBorder(IdeBorderFactory.createEmptyBorder(2, 2, 2, 2));
}
public JComponent createComponent() {
@@ -70,6 +70,7 @@ public class CodeStyleImportsPanel extends JPanel {
public CodeStyleImportsPanel(CodeStyleSettings settings){
mySettings = settings;
setLayout(new BorderLayout());
setBorder(IdeBorderFactory.createEmptyBorder(2, 2, 2, 2));
add(myWholePanel, BorderLayout.CENTER);
myGeneralPanel.add(createGeneralOptionsPanel(), BorderLayout.CENTER);
@@ -1069,23 +1069,12 @@ public class Mappings {
if (overrides.satisfy(mm) && inheritorOf.isValue() && inheritorOf.value()) {
debug("Current method overrides that found");
final Option<Boolean> subtypeOf = u.isSubtypeOf(mm.type, m.type);
final int file = myClassToSourceFile.get(cc.name);
if (Difference.weakerAccess(mm.access, m.access) ||
((m.access & Opcodes.ACC_STATIC) > 0 && (mm.access & Opcodes.ACC_STATIC) == 0) ||
((m.access & Opcodes.ACC_STATIC) == 0 && (mm.access & Opcodes.ACC_STATIC) > 0) ||
((m.access & Opcodes.ACC_FINAL) > 0) ||
!m.exceptions.equals(mm.exceptions) ||
(subtypeOf.isValue() && subtypeOf.value()) ||
(subtypeOf.isNone() || !subtypeOf.value()) ||
!empty(mm.signature) || !empty(m.signature)) {
final int file = myClassToSourceFile.get(cc.name);
if (file > 0) {
final String f = myContext.getValue(file);
debug("Complex condition is satisfied, affecting file ", f);
affectedFiles.add(new File(f));
}
if (file > 0) {
final String f = myContext.getValue(file);
debug("Affecting file ", f);
affectedFiles.add(new File(f));
}
}
else {
@@ -2052,7 +2041,7 @@ public class Mappings {
myDebugS.debug(comment, s);
}
public void toStream (final PrintStream stream) {
public void toStream(final PrintStream stream) {
final Streamable[] data = {
myClassToSubclasses,
myClassToClassDependency,
@@ -2071,7 +2060,7 @@ public class Mappings {
"ClassToSourceFile"
};
for (int i = 0; i<data.length; i++) {
for (int i = 0; i < data.length; i++) {
stream.print("Begin Of ");
stream.println(info[i]);
@@ -23,6 +23,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.codeStyle.CustomCodeStyleSettings;
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.OptionGroup;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBLabel;
@@ -54,6 +55,7 @@ public class CodeStyleBlankLinesPanel extends MultilanguageCodeStyleAbstractPane
public CodeStyleBlankLinesPanel(CodeStyleSettings settings) {
super(settings);
myPanel.setBorder(IdeBorderFactory.createEmptyBorder(2, 2, 2, 2));
init();
}
@@ -25,11 +25,11 @@ import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.FilePathImpl;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangesUtil;
import com.intellij.openapi.vcs.changes.MergeTexts;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.merge.MergeData;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
@@ -97,8 +97,9 @@ public class ConflictedDiffRequestPresentable implements DiffRequestPresentable
CharsetToolkit.bytesToString(mergeData.ORIGINAL, charset), myProject, null, null);
request.setWindowTitle(FileUtil.toSystemDependentName(myFile.getPresentableUrl()));
// todo titles?
request.setVersionTitles(new String[] {myChange.getAfterRevision().getRevisionNumber().asString(),
"Base Version", mergeData.LAST_REVISION_NUMBER.asString()});
VcsRevisionNumber lastRevisionNumber = mergeData.LAST_REVISION_NUMBER;
request.setVersionTitles(new String[]{myChange.getAfterRevision().getRevisionNumber().asString(),
"Base Version", lastRevisionNumber != null ? lastRevisionNumber.asString() : ""});
return new MyResult(request, DiffPresentationReturnValue.useRequest);
}
catch (VcsException e) {
@@ -66,7 +66,6 @@ public class AndroidCommonUtils {
private static final String[] DRAWABLE_EXTENSIONS = new String[]{PNG_EXTENSION, "jpg", "gif"};
@NonNls public static final String RELEASE_BUILD_OPTION = "RELEASE_BUILD_KEY";
@NonNls public static final String LIGHT_BUILD_OPTION = "LIGHT_BUILD_KEY";
@NonNls public static final String PROGUARD_CFG_PATH_OPTION = "ANDROID_PROGUARD_CFG_PATH";
@NonNls public static final String DIRECTORY_FOR_LOGS_NAME = "proguard_logs";
@NonNls public static final String PROGUARD_OUTPUT_JAR_NAME = "obfuscated_sources.jar";
@@ -78,9 +77,16 @@ public class AndroidCommonUtils {
};
@NonNls public static final String INCLUDE_SYSTEM_PROGUARD_FILE_ELEMENT_NAME = "includeSystemProguardFile";
private static final String[] TEST_CONFIGURATION_TYPE_IDS =
{"JUnit", "TestNG", "ScalaTestRunConfiguration", "SpecsRunConfiguration", "Specs2RunConfiguration"};
private AndroidCommonUtils() {
}
public static boolean isTestConfiguration(@NotNull String typeId) {
return ArrayUtil.find(TEST_CONFIGURATION_TYPE_IDS, typeId) >= 0;
}
public static String command2string(@NotNull Collection<String> command) {
final StringBuilder builder = new StringBuilder();
for (Iterator<String> it = command.iterator(); it.hasNext(); ) {
@@ -435,7 +435,8 @@ class AndroidJpsUtil {
}
public static boolean isLightBuild(@NotNull CompileContext context) {
return Boolean.parseBoolean(context.getBuilderParameter(AndroidCommonUtils.LIGHT_BUILD_OPTION));
final String typeId = context.getBuilderParameter("RUN_CONFIGURATION_TYPE_ID");
return typeId != null && AndroidCommonUtils.isTestConfiguration(typeId);
}
public static boolean isReleaseBuild(@NotNull CompileContext context) {
@@ -138,8 +138,7 @@ public class AndroidPackagingBuilder extends ProjectLevelBuilder {
private static boolean runPngCaching(@NotNull CompileContext context,
@NotNull Module module,
@NotNull AndroidFileSetStorage storage,
@Nullable AndroidFileSetState state)
throws IOException {
@Nullable AndroidFileSetState state) throws IOException {
final AndroidFileSetState savedState = storage.getState(module.getName());
if (context.isMake() && savedState != null && savedState.equalsTo(state)) {
return true;
@@ -165,6 +164,14 @@ public class AndroidPackagingBuilder extends ProjectLevelBuilder {
final File resCacheDir = AndroidJpsUtil.getResourcesCacheDir(context, module);
if (context.isProjectRebuild() && resCacheDir.exists()) {
if (!FileUtil.delete(resCacheDir)) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR,
"Cannot delete directory " + resCacheDir.getPath()));
return false;
}
}
if (!resCacheDir.exists()) {
if (!resCacheDir.mkdirs()) {
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR,
@@ -18,6 +18,8 @@ import org.jetbrains.android.util.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ClasspathItem;
import org.jetbrains.jps.ClasspathKind;
import org.jetbrains.jps.Module;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.incremental.*;
@@ -46,6 +48,9 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
@NonNls private static final String PERMISSION_GROUP_TAG = "permission-group";
@NonNls private static final String NAME_ATTRIBUTE = "name";
private static final int MIN_PLATFORM_TOOLS_REVISION = 11;
private static final int MIN_SDK_TOOLS_REVISION = 19;
public AndroidSourceGeneratingBuilder() {
super(BuilderCategory.SOURCE_GENERATOR);
}
@@ -70,6 +75,16 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
}
private static ModuleLevelBuilder.ExitCode doBuild(CompileContext context, ModuleChunk chunk) throws IOException {
final Map<Module, MyModuleData> moduleDataMap = computeModuleDatas(chunk.getModules(), context);
if (moduleDataMap == null || moduleDataMap.size() == 0) {
return ExitCode.ABORT;
}
if (!checkVersions(moduleDataMap, context)) {
return ExitCode.ABORT;
}
checkAndroidDependencies(moduleDataMap, context);
final Map<File, Module> idlFilesToCompile = new HashMap<File, Module>();
final Map<File, Module> rsFilesToCompile = new HashMap<File, Module>();
@@ -93,12 +108,6 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
return true;
}
});
final Map<Module, MyModuleData> moduleDataMap = computeModuleDatas(chunk.getModules(), context);
if (moduleDataMap == null || moduleDataMap.size() == 0) {
return ExitCode.ABORT;
}
boolean success = true;
if (context.isProjectRebuild()) {
@@ -154,6 +163,75 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
return success ? ExitCode.OK : ExitCode.ABORT;
}
private static boolean checkVersions(@NotNull Map<Module, MyModuleData> dataMap, @NotNull CompileContext context) {
for (Map.Entry<Module, MyModuleData> entry : dataMap.entrySet()) {
final Module module = entry.getKey();
final AndroidPlatform platform = entry.getValue().getPlatform();
boolean success = true;
final int platformToolsRevision = platform.getPlatformToolsRevision();
if (platformToolsRevision >= 0 && platformToolsRevision < MIN_PLATFORM_TOOLS_REVISION) {
final String message = '[' +
module.getName() +
"] Incompatible version of Android SDK Platform-tools package. Min version is " +
MIN_PLATFORM_TOOLS_REVISION +
". Please, update it though SDK manager";
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message));
success = false;
}
final int sdkToolsRevision = platform.getSdkToolsRevision();
if (sdkToolsRevision >= 0 && sdkToolsRevision < MIN_SDK_TOOLS_REVISION) {
final String message = '[' +
module.getName() +
"] Incompatible version of Android SDK Tools package. Min version is " +
MIN_SDK_TOOLS_REVISION +
". Please, update it though SDK manager";
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.ERROR, message));
success = false;
}
// show error message only for first module, because all modules usualy have the same sdk specified
if (!success) {
return false;
}
}
return true;
}
private static void checkAndroidDependencies(@NotNull Map<Module, MyModuleData> moduleDataMap, @NotNull CompileContext context) {
for (Map.Entry<Module, MyModuleData> entry : moduleDataMap.entrySet()) {
final Module module = entry.getKey();
final MyModuleData moduleData = entry.getValue();
final AndroidFacet facet = moduleData.getFacet();
if (facet.isLibrary()) {
continue;
}
for (ClasspathItem item : module.getClasspath(ClasspathKind.PRODUCTION_RUNTIME, false)) {
if (item instanceof Module) {
final Module depModule = (Module)item;
final AndroidFacet depFacet = AndroidJpsUtil.getFacet(depModule);
if (depFacet != null && !depFacet.isLibrary()) {
String message = "Suspicious module dependency " +
module.getName() +
" -> " +
depModule.getName() +
": Android application module depends on other application module. Possibly, you should ";
if (AndroidJpsUtil.isMavenizedModule(depModule)) {
message += "change packaging type of module " + depModule.getName() + " to 'apklib' in pom.xml file or ";
}
message += "change dependency scope to 'Provided'.";
context.processMessage(new CompilerMessage(BUILDER_NAME, BuildMessage.Kind.WARNING, message));
}
}
}
}
}
private static boolean runBuildConfigGeneration(@NotNull CompileContext context,
@NotNull Map<Module, MyModuleData> moduleDataMap,
@NotNull AndroidBuildConfigStateStorage storage) {
@@ -276,7 +354,7 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
continue;
}
final IAndroidTarget target = moduleData.getAndroidTarget();
final IAndroidTarget target = moduleData.getPlatform().getTarget();
try {
final File[] sourceRoots = AndroidJpsUtil.getSourceRootsForModuleAndDependencies(module);
@@ -353,8 +431,9 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
continue;
}
final IAndroidTarget target = moduleData.getAndroidTarget();
final String sdkLocation = moduleData.getSdkLocation();
final AndroidPlatform platform = moduleData.getPlatform();
final IAndroidTarget target = platform.getTarget();
final String sdkLocation = platform.getSdk().getSdkPath();
final String filePath = file.getPath();
File tmpOutputDirectory = null;
@@ -414,7 +493,7 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
final File generatedSourcesDir = AndroidJpsUtil.getGeneratedSourcesStorage(module);
final File aptOutputDirectory = new File(generatedSourcesDir, AndroidJpsUtil.AAPT_GENERATED_SOURCE_ROOT_NAME);
final IAndroidTarget target = moduleData.getAndroidTarget();
final IAndroidTarget target = moduleData.getPlatform().getTarget();
try {
if (!needToRunAaptCompilation(facet)) {
@@ -777,8 +856,6 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
success = false;
continue;
}
final AndroidSdk androidSdk = platform.getSdk();
final IAndroidTarget target = platform.getTarget();
final File manifestFile = AndroidJpsUtil.getManifestFileForCompilationPath(facet);
if (manifestFile == null || !manifestFile.exists()) {
@@ -796,7 +873,7 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
continue;
}
moduleDataMap.put(module, new MyModuleData(androidSdk.getSdkPath(), target, facet, manifestFile, packageName));
moduleDataMap.put(module, new MyModuleData(platform, facet, manifestFile, packageName));
}
return success ? moduleDataMap : null;
@@ -883,32 +960,24 @@ public class AndroidSourceGeneratingBuilder extends ModuleLevelBuilder {
}
private static class MyModuleData {
private final String mySdkLocation;
private final IAndroidTarget myAndroidTarget;
private final AndroidPlatform myPlatform;
private final AndroidFacet myFacet;
private final File myManifestFileForCompiler;
private final String myPackage;
private MyModuleData(@NotNull String sdkLocation,
@NotNull IAndroidTarget androidTarget,
private MyModuleData(@NotNull AndroidPlatform platform,
@NotNull AndroidFacet facet,
@NotNull File manifestFileForCompiler,
@NotNull String aPackage) {
mySdkLocation = sdkLocation;
myAndroidTarget = androidTarget;
myPlatform = platform;
myFacet = facet;
myManifestFileForCompiler = manifestFileForCompiler;
myPackage = aPackage;
}
@NotNull
public IAndroidTarget getAndroidTarget() {
return myAndroidTarget;
}
@NotNull
public String getSdkLocation() {
return mySdkLocation;
public AndroidPlatform getPlatform() {
return myPlatform;
}
@NotNull
@@ -24,7 +24,6 @@ import com.intellij.compiler.impl.ModuleCompileScope;
import com.intellij.compiler.options.CompileStepBeforeRun;
import com.intellij.compiler.progress.CompilerTask;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.execution.junit.JUnitConfiguration;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.compiler.*;
@@ -88,10 +87,6 @@ public class AndroidCompileUtil {
@NonNls public static final String PROGUARD_CFG_FILE_NAME = "proguard-project.txt";
@NonNls public static final String OLD_PROGUARD_CFG_FILE_NAME = "proguard.cfg";
@NonNls
private static final String[] SCALA_TEST_CONFIGURATIONS =
{"ScalaTestRunConfiguration", "SpecsRunConfiguration", "Specs2RunConfiguration"};
private AndroidCompileUtil() {
}
@@ -622,23 +617,8 @@ public class AndroidCompileUtil {
}
public static boolean isFullBuild(@NotNull CompileContext context) {
final RunConfiguration runConfiguration = CompileStepBeforeRun.getRunConfiguration(context);
if (runConfiguration == null) {
return true;
}
if (runConfiguration instanceof JUnitConfiguration) {
return false;
}
for (AndroidLightBuildProvider provider : AndroidLightBuildProvider.EP_NAME.getExtensions()) {
if (provider.toPerformLightBuild(runConfiguration)) {
return false;
}
}
final String id = runConfiguration.getType().getId();
return ArrayUtil.find(SCALA_TEST_CONFIGURATIONS, id) < 0;
final RunConfiguration c = CompileStepBeforeRun.getRunConfiguration(context);
return c == null || !AndroidCommonUtils.isTestConfiguration(c.getType().getId());
}
public static boolean isReleaseBuild(@NotNull CompileContext context) {
@@ -32,7 +32,6 @@ import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.roots.ModuleOrderEntry;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEntry;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -41,7 +40,6 @@ import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.maven.AndroidMavenUtil;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
@@ -54,7 +52,6 @@ import java.util.Set;
*/
public class AndroidPrecompileTask implements CompileTask {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.compiler.AndroidPrecompileTask");
private static final Key<String> LIGHT_BUILD_KEY = Key.create(AndroidCommonUtils.LIGHT_BUILD_OPTION);
@Override
public boolean execute(CompileContext context) {
@@ -97,6 +94,7 @@ public class AndroidPrecompileTask implements CompileTask {
excludeAllSourceRoots(module, configuration, addedEntries);
}
else {
// todo: support this by project converter to use on compile-server
unexcludeAllSourceRoots(facet, configuration);
}
}
@@ -106,10 +104,6 @@ public class AndroidPrecompileTask implements CompileTask {
LOG.debug("Files excluded by Android: " + addedEntries.size());
CompilerManager.getInstance(project).addCompilationStatusListener(new MyCompilationStatusListener(project, addedEntries), project);
}
if (!AndroidCompileUtil.isFullBuild(context)) {
context.getCompileScope().putUserData(LIGHT_BUILD_KEY, Boolean.toString(true));
}
return true;
}
+3 -1
View File
@@ -101,7 +101,9 @@ public class GitBranch extends GitReference {
*/
public static Pair<String, String> splitNameOfRemoteBranch(String branchName) {
int firstSlash = branchName.indexOf('/');
return Pair.create(branchName.substring(0, firstSlash), branchName.substring(firstSlash + 1));
String remoteName = firstSlash > -1 ? branchName.substring(0, firstSlash) : branchName;
String remoteBranchName = branchName.substring(firstSlash + 1);
return Pair.create(remoteName, remoteBranchName);
}
/**
@@ -114,6 +114,14 @@ public class GitUtil {
else {
pathToDir = content;
}
if (!FileUtil.isAbsolute(pathToDir)) {
String canonicalPath = FileUtil.toCanonicalPath(FileUtil.join(rootDir.getPath(), pathToDir));
if (canonicalPath == null) {
return null;
}
pathToDir = FileUtil.toSystemIndependentName(canonicalPath);
}
return VcsUtil.getVirtualFile(pathToDir);
}
@@ -48,9 +48,11 @@ public class GitStash extends GitRepositoryAction {
if (!d.isOK()) {
return;
}
affectedRoots.add(d.getGitRoot());
VirtualFile root = d.getGitRoot();
affectedRoots.add(root);
final GitLineHandler h = d.handler();
GitHandlerUtil.doSynchronously(h, GitBundle.getString("stashing.title"), h.printableCommandLine());
root.refresh(true, true);
}
/**
@@ -15,6 +15,7 @@
*/
package git4idea.changes;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -50,6 +51,8 @@ public class GitChangeUtils {
*/
public static final String COMMITTED_CHANGELIST_FORMAT = "%ct%n%H%n%P%n%an%x20%x3C%ae%x3E%n%cn%x20%x3C%ce%x3E%n%s%n%x03%n%b%n%x03";
private static final Logger LOG = Logger.getInstance(GitChangeUtils.class);
/**
* A private constructor for utility class
*/
@@ -194,11 +197,17 @@ public class GitChangeUtils {
handler.endOptions();
handler.setNoSSH(true);
handler.setSilent(true);
//handler.setSilent(true);
String output = handler.run();
StringTokenizer stk = new StringTokenizer(output, "\n\r \t", false);
if (!stk.hasMoreTokens()) {
throw new VcsException("The string '" + revisionNumber + "' does not represents a revision number. Output: [" + output + "]");
GitSimpleHandler dh = new GitSimpleHandler(project, vcsRoot, GitCommand.LOG);
dh.addParameters("-1", "HEAD");
dh.setNoSSH(true);
dh.setSilent(true);
String out = dh.run();
LOG.info("Diagnostic output from 'git log -1 HEAD': [" + out + "]");
throw new VcsException(String.format("The string '%s' does not represent a revision number. Output: [%s]\n Root: %s",
revisionNumber, output, vcsRoot));
}
Date timestamp = GitUtil.parseTimestampWithNFEReport(stk.nextToken(), handler, output);
return new GitRevisionNumber(stk.nextToken(), timestamp);
@@ -557,6 +557,12 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
myDirtyScopeManager.dirDirtyRecursively(root);
}
public void reset() {
myNextCommitAmend = false;
myNextCommitAuthor = null;
myNextCommitIsPushed = null;
}
/**
* Checkin options for git
*/
@@ -642,9 +648,8 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
*/
public void refresh() {
myAuthor.setSelectedItem("");
myNextCommitAuthor = null;
myAmend.setSelected(false);
myNextCommitIsPushed = null;
reset();
}
/**
@@ -34,6 +34,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.WaitForProgressToShow;
import git4idea.PlatformFacade;
import git4idea.checkin.GitCheckinEnvironment;
import git4idea.commands.Git;
import git4idea.commands.GitCommandResult;
import git4idea.commands.GitMessageWithFilesDetector;
@@ -59,6 +60,12 @@ import static git4idea.commands.GitSimpleEventDetector.Event.LOCAL_CHANGES_OVERW
public class CherryPicker {
/**
* Name of the {@code .git/CHERRY_PICK_HEAD} file which is stored under {@code .git} when cherry-pick is in progress,
* and contains the hash of the commit being cherry-picked.
*/
private static final String CHERRY_PICK_HEAD_FILE = "CHERRY_PICK_HEAD";
private static final Logger LOG = Logger.getInstance(CherryPicker.class);
@NotNull private final Project myProject;
@@ -254,7 +261,7 @@ public class CherryPicker {
}
private void removeCherryPickHead(@NotNull GitRepository repository) {
File cherryPickHeadFile = new File(repository.getGitDir().getPath(), "CHERRY_PICK_HEAD");
File cherryPickHeadFile = new File(repository.getGitDir().getPath(), CHERRY_PICK_HEAD_FILE);
final VirtualFile cherryPickHead = myPlatformFacade.getLocalFileSystem().refreshAndFindFileByIoFile(cherryPickHeadFile);
if (cherryPickHead != null && cherryPickHead.exists()) {
@@ -486,8 +493,9 @@ public class CherryPicker {
final Collection<Document> committingDocs = markCommittingDocs();
try {
CheckinEnvironment ce = myPlatformFacade.getVcs(myProject).getCheckinEnvironment();
if (ce != null) {
if (ce != null && ce instanceof GitCheckinEnvironment) {
try {
((GitCheckinEnvironment)ce).reset();
List<VcsException> exceptions = ce.commit(myChanges, myCommitMessage);
VcsDirtyScopeManager.getInstance(myProject).filePathsDirty(ChangesUtil.getPaths(myChanges), null);
if (exceptions != null && !exceptions.isEmpty()) {
@@ -146,7 +146,7 @@ public final class GitHttpAdapter {
}
private static void logException(GitRepository repository, String remoteName, String remoteUrl, Exception e, String operation) {
LOG.info("Exception while " + operation + " " + remoteName + "(" + remoteUrl + ")" + " in " + repository.toLogString(), e);
LOG.error("Exception while " + operation + " " + remoteName + "(" + remoteUrl + ")" + " in " + repository.toLogString(), e);
}
private static GitFetchResult.Type convertToFetchResultType(GeneralResult result) {
@@ -301,6 +301,18 @@ public final class GitHttpAdapter {
rememberPassword(provider);
return GeneralResult.SUCCESS;
}
catch (InvalidRemoteException e) {
if (!noRemoteWithoutGitErrorFixTried && isNoRemoteWithoutDotGitError(e, url)) {
url += ".git";
command.setUrl(url);
provider.setUrl(url);
noRemoteWithoutGitErrorFixTried = true;
// don't "eat" one password entering attempt
//noinspection AssignmentToForLoopParameter
i--;
command.cleanup();
}
}
catch (JGitInternalException e) {
if (authError(e)) {
if (provider.wasCancelled()) { // if user cancels the dialog, just return
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.merge.MergeData;
import com.intellij.openapi.vcs.merge.MergeProvider2;
import com.intellij.openapi.vcs.merge.MergeSession;
@@ -37,6 +38,7 @@ import git4idea.commands.GitSimpleHandler;
import git4idea.util.StringScanner;
import git4idea.i18n.GitBundle;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.HashMap;
@@ -119,12 +121,7 @@ public class GitMergeProvider implements MergeProvider2 {
}
mergeData.CURRENT = loadRevisionCatchingErrors(current);
mergeData.LAST = loadRevisionCatchingErrors(last);
try {
mergeData.LAST_REVISION_NUMBER = GitRevisionNumber.resolve(myProject, root, myReverse ? "HEAD" : "MERGE_HEAD");
}
catch (VcsException e) {
// ignore exception, the null value will be used
}
mergeData.LAST_REVISION_NUMBER = findLastRevisionNumber(root);
}
catch (IOException e) {
throw new IllegalStateException("Failed to load file content", e);
@@ -135,6 +132,33 @@ public class GitMergeProvider implements MergeProvider2 {
return mergeData;
}
@Nullable
private VcsRevisionNumber findLastRevisionNumber(@NotNull VirtualFile root) {
if (myReverse) {
try {
return GitRevisionNumber.resolve(myProject, root, "HEAD");
}
catch (VcsException e) {
log.error("Couldn't resolve the HEAD in " + root, e);
}
}
else {
try {
return GitRevisionNumber.resolve(myProject, root, "MERGE_HEAD");
}
catch (VcsException e) {
log.info("Couldn't resolved the MERGE_HEAD in " + root, e); // this may be not a bug, just cherry-pick
try {
return GitRevisionNumber.resolve(myProject, root, "CHERRY_PICK_HEAD");
}
catch (VcsException e1) {
log.error("Couldn't resolve neither MERGE_HEAD, nor the CHERRY_PICK_HEAD in " + root, e1);
}
}
}
return null;
}
private byte[] loadRevisionCatchingErrors(final GitFileRevision revision) throws VcsException, IOException {
try {
return revision.getContent();
@@ -76,7 +76,7 @@ public class GitRebaseDialog extends DialogWrapper {
/**
* If selected, rebase is interactive
*/
private JCheckBox myInteractiveCheckBox;
protected JCheckBox myInteractiveCheckBox;
/**
* No merges are performed if selected.
*/
@@ -61,7 +61,7 @@ public class GitRebaseLineListener extends GitLineHandlerAdapter {
assert myStatus == null;
myStatus = Status.FINISHED;
}
else if (line.startsWith("Automatic cherry-pick failed. ")) {
else if (line.startsWith("Automatic cherry-pick failed") || line.startsWith("When you have resolved this problem")) {
assert myStatus == null || myStatus == Status.ERROR;
myStatus = Status.CONFLICT;
}
@@ -69,7 +69,7 @@ public class GitRebaseLineListener extends GitLineHandlerAdapter {
assert myStatus == null;
myStatus = myProgressLine == null ? Status.CANCELLED : Status.ERROR;
}
else if (line.startsWith("fatal") || line.startsWith("error: ")) {
else if (line.startsWith("fatal") || line.startsWith("error: ") || line.startsWith("Cannot rebase")) {
if (myStatus != Status.CONFLICT) {
myStatus = Status.ERROR;
}
@@ -97,7 +97,7 @@ public class GitRebaseLineListener extends GitLineHandlerAdapter {
else {
total = current = 0;
}
return new Result(myStatus == null ? Status.ERROR : myStatus, total, current);
return new Result(myStatus == null ? Status.FINISHED : myStatus, total, current);
}
/**
@@ -406,7 +406,8 @@ public class GitUnstashDialog extends DialogWrapper {
if (!d.isOK()) {
return;
}
affectedRoots.add(d.getGitRoot());
VirtualFile root = d.getGitRoot();
affectedRoots.add(root);
GitLineHandler h = d.handler();
final AtomicBoolean conflict = new AtomicBoolean();
@@ -418,9 +419,9 @@ public class GitUnstashDialog extends DialogWrapper {
}
});
int rc = GitHandlerUtil.doSynchronously(h, GitBundle.getString("unstash.unstashing"), h.printableCommandLine(), false);
root.refresh(true, true);
if (conflict.get()) {
VirtualFile root = d.getGitRoot();
boolean conflictsResolved = new UnstashConflictResolver(project, root, d.getSelectedStash()).merge();
LOG.info("loadRoot " + root + ", conflictsResolved: " + conflictsResolved);
} else if (rc != 0) {
@@ -65,6 +65,11 @@ public final class GitFetchResult {
public static GitFetchResult error(Exception error) {
return error(Collections.singletonList(error));
}
@NotNull
public static GitFetchResult error(@NotNull String errorMessage) {
return error(new Exception(errorMessage));
}
public boolean isSuccess() {
return myType == Type.SUCCESS;
@@ -98,6 +98,30 @@ public class GitFetcher {
return fetchResult;
}
@NotNull
public GitFetchResult fetch(@NotNull VirtualFile root, @NotNull String remoteName) {
GitRepository repository = myRepositoryManager.getRepositoryForRoot(root);
if (repository == null) {
return logError("Repository can't be null for " + root, myRepositoryManager.toString());
}
GitRemote remote = GitUtil.findRemoteByName(repository, remoteName);
if (remote == null) {
return logError("Couldn't find remote with the name " + remoteName, null);
}
String url = remote.getFirstUrl();
if (url == null) {
return logError("URL is null for remote " + remote.getName(), null);
}
return fetchRemote(repository, remote, url);
}
private static GitFetchResult logError(@NotNull String message, @Nullable String additionalInfo) {
String addInfo = additionalInfo != null ? "\n" + additionalInfo : "";
LOG.error(message + addInfo);
return GitFetchResult.error(message);
}
@NotNull
private GitFetchResult fetchCurrentRemote(@NotNull GitRepository repository) {
FetchParams fetchParams = getFetchParams(repository);
if (fetchParams.isError()) {
@@ -106,7 +130,11 @@ public class GitFetcher {
GitRemote remote = fetchParams.getRemote();
String url = fetchParams.getUrl();
return fetchRemote(repository, remote, url);
}
@NotNull
private GitFetchResult fetchRemote(@NotNull GitRepository repository, @NotNull GitRemote remote, @NotNull String url) {
if (GitHttpAdapter.shouldUseJGit(url)) {
return GitHttpAdapter.fetch(repository, remote, url, null);
}
@@ -299,7 +327,9 @@ public class GitFetcher {
additionalInfo.put(root, ai);
}
if (!result.isSuccess()) {
displayFetchResult(myProject, result, errorNotificationTitle, getErrors());
Collection<Exception> errors = new ArrayList<Exception>(getErrors());
errors.addAll(result.getErrors());
displayFetchResult(myProject, result, errorNotificationTitle, errors);
return false;
}
}
@@ -30,10 +30,7 @@ import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.*;
/**
* File utilities for the git
@@ -179,7 +176,7 @@ public class GitFileUtils {
String output = handler.run();
List<String> nonIgnoredFiles = new ArrayList<String>(paths.size());
List<String> ignoredPaths = Arrays.asList(StringUtil.splitByLines(output));
Set<String> ignoredPaths = new HashSet<String>(Arrays.asList(StringUtil.splitByLines(output)));
for (String pathToCheck : paths) {
if (!ignoredPaths.contains(pathToCheck)) {
nonIgnoredFiles.add(pathToCheck);
@@ -19,7 +19,9 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
@@ -35,8 +37,13 @@ import git4idea.commands.GitSimpleHandler;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
import git4idea.update.GitFetchResult;
import git4idea.update.GitFetcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.github.ui.GithubLoginDialog;
import java.util.concurrent.atomic.AtomicReference;
/**
* Created by IntelliJ IDEA.
*
@@ -141,7 +148,7 @@ public class GithubRebaseAction extends DumbAwareAction {
final Ref<String> remoteForForkParentRepo = new Ref<String>();
for (GitRemote gitRemote : gitRepository.getRemotes()) {
for (String url : gitRemote.getUrls()) {
if (url.endsWith(parent + ".git")) {
if (url.endsWith("/" + parent + ".git")) {
remoteForForkParentRepo.set(gitRemote.getName());
break;
}
@@ -194,6 +201,10 @@ public class GithubRebaseAction extends DumbAwareAction {
});
}
boolean fetchedSuccessfully = fetchParentOrNotifyError(project, gitRepository, remoteForForkParentRepo.get());
if (!fetchedSuccessfully) {
return;
}
BasicAction.saveAll();
final GithubRebase action = (GithubRebase) ActionManager.getInstance().getAction("Github.Rebase.Internal");
action.setRebaseOrigin(remoteForForkParentRepo.get());
@@ -202,6 +213,23 @@ public class GithubRebaseAction extends DumbAwareAction {
action.actionPerformed(actionEvent);
}
private static boolean fetchParentOrNotifyError(@NotNull final Project project, @NotNull final GitRepository repository,
@NotNull final String remote) {
final AtomicReference<GitFetchResult> fetchResult = new AtomicReference<GitFetchResult>();
ProgressManager.getInstance().run(new Task.Modal(project, "Fetching " + remote, false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
fetchResult.set(new GitFetcher(project, indicator, false).fetch(repository.getRoot(), remote));
}
});
GitFetchResult result = fetchResult.get();
if (!result.isSuccess()) {
GitFetcher.displayFetchResult(project, result, null, result.getErrors());
return false;
}
return true;
}
private void showErrorMessageInEDT(final Project project, final String message) {
UIUtil.invokeLaterIfNeeded(new Runnable(){
@Override
@@ -41,6 +41,7 @@ public class GithubRebaseDialog extends GitRebaseDialog {
public void configure(final String originName) {
setTitle("Rebase GitHub");
myInteractiveCheckBox.setSelected(false);
myShowRemoteBranchesCheckBox.setSelected(true);
myShowRemoteBranchesCheckBox.getParent().remove(myShowRemoteBranchesCheckBox);
myGitRootComboBox.setEnabled(false);
@@ -35,16 +35,20 @@ class AlignmentProvider {
private final Map<PsiElement, Set<PsiElement>> myTree = new HashMap<PsiElement, Set<PsiElement>>();
private final Map<Set<PsiElement>, Alignment> myAlignments = new HashMap<Set<PsiElement>, Alignment>();
private final Map<Set<PsiElement>, Boolean> myAllowBackwardShift = new HashMap<Set<PsiElement>, Boolean>();
public void addPair(PsiElement e1, PsiElement e2) {
public void addPair(PsiElement e1, PsiElement e2, Boolean allowBackwardShift) {
LOG.assertTrue(e1 != e2);
final Set<PsiElement> set1 = myTree.get(e1);
final Set<PsiElement> set2 = myTree.get(e2);
LOG.assertTrue(set1 == null || set2 == null || !myAlignments.containsKey(set1) || !myAlignments.containsKey(set2));
if (set1 != null && set2 != null) {
LOG.assertTrue(!myAlignments.containsKey(set1) || !myAlignments.containsKey(set2));
LOG.assertTrue(myAllowBackwardShift.get(set1).booleanValue() == myAllowBackwardShift.get(set2).booleanValue());
if (allowBackwardShift != null) {
LOG.assertTrue(myAllowBackwardShift.get(set1).booleanValue() == allowBackwardShift.booleanValue());
}
if (myAlignments.containsKey(set2)) {
for (Iterator<PsiElement> iterator = set1.iterator(); iterator.hasNext(); ) {
PsiElement element = iterator.next();
@@ -64,15 +68,23 @@ class AlignmentProvider {
}
}
else if (set1 != null) {
if (allowBackwardShift != null) {
LOG.assertTrue(myAllowBackwardShift.get(set1).booleanValue() == allowBackwardShift.booleanValue());
}
addInternal(set1, e2);
}
else if (set2 != null) {
if (allowBackwardShift != null) {
LOG.assertTrue(myAllowBackwardShift.get(set2).booleanValue() == allowBackwardShift.booleanValue());
}
addInternal(set2, e1);
}
else {
final HashSet<PsiElement> set = createHashSet();
addInternal(set, e1);
addInternal(set, e2);
myAllowBackwardShift.put(set, allowBackwardShift);
}
}
@@ -92,16 +104,17 @@ class AlignmentProvider {
};
}
public void addPair(ASTNode node1, ASTNode node2) {
addPair(node1.getPsi(), node2.getPsi());
public void addPair(ASTNode node1, ASTNode node2, boolean allowBackwardShift) {
addPair(node1.getPsi(), node2.getPsi(), allowBackwardShift);
}
private void add(PsiElement element) {
private void add(PsiElement element, boolean allowBackwardShift) {
if (myTree.get(element) != null) return;
final HashSet<PsiElement> set = createHashSet();
set.add(element);
myTree.put(element, set);
myAllowBackwardShift.put(set, allowBackwardShift);
}
@Nullable
@@ -114,17 +127,19 @@ class AlignmentProvider {
Alignment alignment = myAlignments.get(set);
if (alignment != null) return alignment;
alignment = Alignment.createAlignment(true);
alignment = Alignment.createAlignment(myAllowBackwardShift.get(set));
myAlignments.put(set, alignment);
return alignment;
}
public Aligner createAligner(PsiElement expression) {
return new Aligner(expression);
public Aligner createAligner(PsiElement expression, boolean allowBackwardShift) {
Aligner aligner = new Aligner(allowBackwardShift);
aligner.append(expression);
return aligner;
}
public Aligner createAligner() {
return new Aligner();
public Aligner createAligner(boolean allowBackwardShift) {
return new Aligner(allowBackwardShift);
}
/**
@@ -135,12 +150,10 @@ class AlignmentProvider {
*/
class Aligner {
private PsiElement myRef = null;
private boolean allowBackwardShift = true;
private Aligner() {
}
private Aligner(PsiElement initial) {
myRef = initial;
Aligner(boolean allowBackwardShift) {
this.allowBackwardShift = allowBackwardShift;
}
void append(@Nullable PsiElement element) {
@@ -148,10 +161,10 @@ class AlignmentProvider {
if (myRef == null) {
myRef = element;
add(element);
add(element, allowBackwardShift);
}
else {
addPair(myRef, element);
addPair(myRef, element, allowBackwardShift);
}
}
}
@@ -139,7 +139,7 @@ public class GeeseUtil {
break;
}
}
alignments.addPair(rBrace, cur);
alignments.addPair(rBrace, cur, true);
}
public static boolean isClosureContainLF(PsiElement rBrace) {
@@ -49,7 +49,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrLabeledStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
@@ -137,7 +139,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
if (childNode.getTextRange().getLength() > 0) {
final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode);
if (myAlignment != null) {
myAlignmentProvider.addPair(myNode, childNode);
myAlignmentProvider.addPair(myNode, childNode, true);
}
subBlocks.add(new GroovyBlock(childNode, indent, myWrap, mySettings, myGroovySettings, myAlignmentProvider));
}
@@ -148,18 +150,32 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
// chained properties, calls, indexing, etc
if (NESTED.contains(myNode.getElementType()) && blockPsi.getParent() != null && !NESTED.contains(blockPsi.getParent().getNode().getElementType())) {
final List<Block> subBlocks = new ArrayList<Block>();
AlignmentProvider.Aligner dotsAligner = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? myAlignmentProvider.createAligner() : null;
AlignmentProvider.Aligner dotsAligner = mySettings.ALIGN_MULTILINE_CHAINED_METHODS ? myAlignmentProvider.createAligner(true) : null;
addNestedChildren(myNode.getPsi(), subBlocks, dotsAligner, true);
return subBlocks;
}
if (blockPsi instanceof GrListOrMap && ((GrListOrMap)blockPsi).isMap() && myGroovySettings.ALIGN_NAMED_ARGS_IN_MAP) {
AlignmentProvider.Aligner labels = myAlignmentProvider.createAligner(false);
AlignmentProvider.Aligner exprs = myAlignmentProvider.createAligner(true);
GrNamedArgument[] namedArgs = ((GrListOrMap)blockPsi).getNamedArguments();
for (GrNamedArgument arg : namedArgs) {
GrArgumentLabel label = arg.getLabel();
if (label != null) labels.append(label);
PsiElement colon = arg.getColon();
if (colon == null) colon = arg.getExpression();
if (colon != null) exprs.append(colon);
}
}
// For Parameter lists
if (isListLikeClause(blockPsi)) {
final ArrayList<Block> subBlocks = new ArrayList<Block>();
List<ASTNode> astNodes = visibleChildren(myNode);
if (mustAlign(blockPsi, astNodes)) {
final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner();
final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner(false);
for (ASTNode node : astNodes) {
if (!isKeyword(node)) aligner.append(node.getPsi());
}
@@ -178,7 +194,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
final ArrayList<Block> subBlocks = new ArrayList<Block>();
if (classLevel && myAlignment != null) {
final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner();
final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner(true);
for (ASTNode child : children) {
aligner.append(child.getPsi());
}
@@ -212,7 +228,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
else {
currentGroup = new ArrayList<AlignmentProvider.Aligner>();
for (LeafPsiElement expression : table) {
currentGroup.add(myAlignmentProvider.createAligner(expression));
currentGroup.add(myAlignmentProvider.createAligner(expression, true));
}
}
}
@@ -228,9 +244,9 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
if (variables.length > 0) {
if (!classLevel || currentGroup == null || fieldGroupEnded(psi)) {
currentGroup = new ArrayList<AlignmentProvider.Aligner>();
currentGroup.add(myAlignmentProvider.createAligner());
currentGroup.add(myAlignmentProvider.createAligner());
currentGroup.add(myAlignmentProvider.createAligner());
currentGroup.add(myAlignmentProvider.createAligner(true));
currentGroup.add(myAlignmentProvider.createAligner(true));
currentGroup.add(myAlignmentProvider.createAligner(true));
}
AlignmentProvider.Aligner varName = currentGroup.get(1);
@@ -304,8 +320,10 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
// println 'xxx'
// })
if (blockPsi instanceof GrArgumentList && mySettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS) {
return children.size() != 3 || children.get(0).getElementType() != mLPAREN
|| children.get(1).getElementType() != CLOSABLE_BLOCK || children.get(2).getElementType() != mRPAREN;
return !(children.size() == 3 &&
children.get(0).getElementType() == mLPAREN &&
(children.get(1).getElementType() == CLOSABLE_BLOCK || children.get(1).getElementType() == LIST_OR_MAP) &&
children.get(2).getElementType() == mRPAREN);
}
if (blockPsi instanceof GrAssignmentExpression && ((GrAssignmentExpression)blockPsi).getRValue() instanceof GrAssignmentExpression) {
@@ -426,7 +444,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
private List<Block> generateForBinaryExpr() {
final ArrayList<Block> subBlocks = new ArrayList<Block>();
AlignmentProvider.Aligner
alignment = mySettings.ALIGN_MULTILINE_BINARY_OPERATION ? myAlignmentProvider.createAligner() : null;
alignment = mySettings.ALIGN_MULTILINE_BINARY_OPERATION ? myAlignmentProvider.createAligner(true) : null;
GrBinaryExpression binary = (GrBinaryExpression)myNode.getPsi();
LOG.assertTrue(binary != null);
@@ -44,6 +44,7 @@ public class GroovyCodeStyleSettings extends CustomCodeStyleSettings {
public boolean SPACE_IN_NAMED_ARGUMENT = true;
public boolean ALIGN_MULTILINE_LIST_OR_MAP = false;
public boolean SPACE_WITHIN_LIST_OR_MAP = false;
public boolean ALIGN_NAMED_ARGS_IN_MAP = false;
public GroovyCodeStyleSettings(CodeStyleSettings container) {
super("GroovyCodeStyleSettings", container);
@@ -43,8 +43,10 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe
@NotNull SettingsType settingsType) {
if (settingsType == SettingsType.WRAPPING_AND_BRACES_SETTINGS) {
consumer.showAllStandardOptions();
consumer.showCustomOption(GroovyCodeStyleSettings.class, "USE_FLYING_GEESE_BRACES", "Use flying geese braces", CodeStyleSettingsCustomizable.WRAPPING_BRACES);
consumer.showCustomOption(GroovyCodeStyleSettings.class, "USE_FLYING_GEESE_BRACES", "Use flying geese braces",
CodeStyleSettingsCustomizable.WRAPPING_BRACES);
consumer.showCustomOption(GroovyCodeStyleSettings.class, "ALIGN_MULTILINE_LIST_OR_MAP", "Align when multiple", "List and map literals");
consumer.showCustomOption(GroovyCodeStyleSettings.class, "ALIGN_NAMED_ARGS_IN_MAP", "Align named arguments", "List and map literals");
return;
}
if (settingsType == SettingsType.SPACING_SETTINGS) {
@@ -268,6 +270,10 @@ public class GroovyLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSe
" label: " +
" if (2 < 3) return else if (2 > 3) return else return\n" +
" for (int i = 0; i < 0xFFFFFF; i += 2) System.out.println(i)\n" +
" print([\n" +
" l1: expr1,\n" +
" label2: expr2\n" +
" ])\n" +
" while (x < 50000) x++\n" +
" switch (a) {\n" +
" case 0:\n" +
@@ -138,12 +138,6 @@ public abstract class GroovyIndentProcessor implements GroovyElementTypes {
}
}
if (psiParent instanceof GrListOrMap) {
if (child.getElementType() != mLBRACK && child.getElementType() != mRBRACK /*&& child.getElementType() != mCOMMA*/) {
return Indent.getContinuationWithoutFirstIndent();
}
}
if ((psiParent instanceof GrDocComment &&
child.getElementType() != mGDOC_COMMENT_START) ||
psiParent instanceof GrDocTag &&
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
@@ -34,4 +35,7 @@ public interface GrNamedArgument extends GroovyPsiElement {
@Nullable
String getLabelName();
@Nullable
PsiElement getColon();
}
@@ -17,8 +17,10 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.arguments;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
@@ -59,4 +61,10 @@ public class GrNamedArgumentImpl extends GroovyPsiElementImpl implements GrNamed
final GrArgumentLabel label = getLabel();
return label == null ? null : label.getName();
}
@Nullable
@Override
public PsiElement getColon() {
return findChildByType(GroovyTokenTypes.mCOLON);
}
}
@@ -235,6 +235,12 @@ public class FormatterTest extends GroovyFormatterTestCase {
public void testGeese7() {doGeeseTest();}
public void testGeese8() {doGeeseTest();}
public void testMapInArgumentList() {doTest();}
public void testMapInArgumentList2() {
myTempSettings.getCustomSettings(GroovyCodeStyleSettings.class).ALIGN_NAMED_ARGS_IN_MAP = true;
doTest();
}
private void doGeeseTest() {
GroovyCodeStyleSettings customSettings = myTempSettings.getCustomSettings(GroovyCodeStyleSettings.class);
boolean oldvalue = customSettings.USE_FLYING_GEESE_BRACES;
@@ -0,0 +1,13 @@
test(
changesSorter: [
(GradleMismatchedLibraryPathChange): 2,
(GradleLibraryDependencyPresenceChange): 1
]
)
-----
test(
changesSorter: [
(GradleMismatchedLibraryPathChange) : 2,
(GradleLibraryDependencyPresenceChange): 1
]
)
@@ -0,0 +1,13 @@
test(
changesSorter: [
(GradleMismatchedLibraryPathChange): 2,
(GradleLibraryDependencyPresenceChange): 1
]
)
-----
test(
changesSorter: [
(GradleMismatchedLibraryPathChange): 2,
(GradleLibraryDependencyPresenceChange): 1
]
)