diff --git a/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy b/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy index 8b495f85c6fd..f2348fdb8dbd 100644 --- a/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/IdeaCommunityProperties.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,6 +89,10 @@ class IdeaCommunityProperties extends BaseIdeaProperties { return new LinuxDistributionCustomizer() { { iconPngPath = "$projectHome/platform/icons/src/icon_CE_128.png" + //snapName = "intellij-idea-community" + //snapDescription = + // "The most intelligent Java IDE. Every aspect of IntelliJ IDEA is specifically designed to maximize developer productivity. " + + // "Together, powerful static code analysis and ergonomic design make development not only productive but also an enjoyable experience." } @Override diff --git a/build/snap/idea-snap.properties b/build/snap/idea-snap.properties new file mode 100644 index 000000000000..2afae5831d38 --- /dev/null +++ b/build/snap/idea-snap.properties @@ -0,0 +1,6 @@ + +#----------------------------------------------------------------------- +# Snap-specific properties +#----------------------------------------------------------------------- +idea.skip.desktop.entry.step=true +ide.no.platform.update=Snap diff --git a/build/snap/snapcraft-template.yaml b/build/snap/snapcraft-template.yaml new file mode 100644 index 000000000000..9b18cc86b37d --- /dev/null +++ b/build/snap/snapcraft-template.yaml @@ -0,0 +1,25 @@ +# see platform/build-scripts/.../LinuxDistributionBuilder.groovy + +name: $NAME$ +version: '$VERSION$' +icon: $NAME$.png +summary: $SUMMARY$ +description: $DESCRIPTION$ +grade: stable +confinement: classic +architectures: [amd64] + +apps: + $NAME$: + command: $SCRIPT$ + +parts: + common: + plugin: dump + source: dist.all + bins: + plugin: dump + source: dist.unix + jre: + plugin: dump + source: jre \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/TypeExpression.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/TypeExpression.java index 34c589e71f97..53b98c154bae 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/TypeExpression.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/TypeExpression.java @@ -25,6 +25,8 @@ import com.intellij.codeInsight.template.impl.JavaTemplateUtil; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -60,7 +62,8 @@ public class TypeExpression extends Expression { @Override public String toString() { - return myItems.size() == 1 ? super.toString() : type.getPresentableText(); + final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); + return myItems.size() == 1 || settings.isUseFqClassNames() ? super.toString() : type.getPresentableText(); } }; } diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java index ad34ea7d2c21..243d6307fea7 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaMethodProcessor.java @@ -124,7 +124,7 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor { qualifyOuterMemberReferences(outerHides); qualifyStaticImportReferences(staticImportHides); - if (!method.isConstructor() && method.findDeepestSuperMethods().length == 0) { + if (!method.isConstructor() && method.isPhysical() && method.findDeepestSuperMethods().length == 0) { PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, true, CommonClassNames.JAVA_LANG_OVERRIDE); if (annotation != null && annotation.isPhysical()) { annotation.delete(); diff --git a/java/java-tests/testData/codeInspection/redundantLambdaParameterType/NotApplicableDueToChainedCall.java b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/NotApplicableDueToChainedCall.java new file mode 100644 index 000000000000..da3c6fe0ad73 --- /dev/null +++ b/java/java-tests/testData/codeInspection/redundantLambdaParameterType/NotApplicableDueToChainedCall.java @@ -0,0 +1,16 @@ +import java.util.ArrayList; +import java.util.Comparator; + +public final class Main { + public static void main(final String[] args) { + new ArrayList().sort(Comparator.comparingInt((Node node) -> node.value).reversed()); + } + + static class Node { + private final int value; + + Node(final int value) { + this.value = value; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/CreateMethodFromUsageTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/CreateMethodFromUsageTest.groovy index 4e71ece1a90c..d13c386533d8 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/CreateMethodFromUsageTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/CreateMethodFromUsageTest.groovy @@ -26,6 +26,8 @@ import com.intellij.openapi.editor.actionSystem.EditorActionManager import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiMethod import com.intellij.psi.PsiModifier +import com.intellij.psi.codeStyle.CodeStyleSettings +import com.intellij.psi.codeStyle.CodeStyleSettingsManager import com.intellij.psi.util.PsiTreeUtil /** * @author ven @@ -173,6 +175,53 @@ class A { } + void "test use fully qualified names with conflicting imports"() { + final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); + def fqClassNames = settings.useFqClassNames + try { + settings.setUseFqClassNames(true) + configureFromFileText "a.java", """ + import java.awt.List; + class A { + void m(java.util.List list){ + foo(list); + } + } + """ + TemplateManagerImpl.setTemplateTesting(project, testRootDisposable) + doAction("Create method 'foo'") + def state = TemplateManagerImpl.getTemplateState(getEditor()) + + def document = getEditor().getDocument() + def offset = getEditor().getCaretModel().getOffset() + + ApplicationManager.application.runWriteAction { + def method = PsiTreeUtil.getParentOfType(getFile().findElementAt(offset), PsiMethod.class) + method.getModifierList().setModifierProperty(PsiModifier.STATIC, false) + PsiDocumentManager.getInstance(getFile().project).commitDocument(document) + } + + state.gotoEnd(false) + + checkResultByText """ + import java.awt.List; + class A { + void m(java.util.List list){ + foo(list); + } + + private void foo(java.util.List list) { + + } + } + """ + } + finally { + settings.setUseFqClassNames(fqClassNames) + } + + } + @Override protected String getBasePath() { return "/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromUsage" diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeInspectionTest.java index 1121070a6c02..82b3b3955500 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/RedundantLambdaParameterTypeInspectionTest.java @@ -26,7 +26,7 @@ import java.util.List; public class RedundantLambdaParameterTypeInspectionTest extends LightCodeInsightFixtureTestCase { private RedundantLambdaParameterTypeInspection myInspection = new RedundantLambdaParameterTypeInspection(); - private final String myIntentionName = "Remove redundant parameter types"; + private static final String ourIntentionName = "Remove redundant parameter types"; @Override protected String getBasePath() { @@ -91,20 +91,24 @@ public class RedundantLambdaParameterTypeInspectionTest extends LightCodeInsight assertIntentionNotAvailable(); } - public void _testInChain() { // disabled till the functionality is available + public void testInChain() { // disabled till the functionality is available doTest(); } + public void testNotApplicableDueToChainedCall() throws Exception { + assertIntentionNotAvailable(); + } + private void doTest() { myFixture.configureByFiles(getTestName(false) + ".java"); - final IntentionAction singleIntention = myFixture.findSingleIntention(myIntentionName); + final IntentionAction singleIntention = myFixture.findSingleIntention(ourIntentionName); myFixture.launchAction(singleIntention); myFixture.checkResultByFile(getTestName(false) + ".java", getTestName(false) + "_after.java", true); } private void assertIntentionNotAvailable() { myFixture.configureByFiles(getTestName(false) + ".java"); - final List intentionActions = myFixture.filterAvailableIntentions(myIntentionName); - assertEmpty(myIntentionName + " is not expected", intentionActions); + final List intentionActions = myFixture.filterAvailableIntentions(ourIntentionName); + assertEmpty(ourIntentionName + " is not expected", intentionActions); } } \ No newline at end of file diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildOptions.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildOptions.groovy index 06abe02a0ad2..211312a7ac45 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildOptions.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildOptions.groovy @@ -68,6 +68,12 @@ class BuildOptions { public static final String BUILD_DMG_WITHOUT_BUNDLED_JRE = "intellij.build.dmg.without.bundled.jre" boolean buildDmgWithoutBundledJre = SystemProperties.getBooleanProperty(BUILD_DMG_WITHOUT_BUNDLED_JRE, SystemProperties.getBooleanProperty("artifact.mac.no.jdk", false)) + /** + * Pass 'true' to this system property to produce .snap packages. + * A build configuration should have "docker.version >= 17" in requirements. + */ + boolean buildUnixSnaps = SystemProperties.getBooleanProperty("intellij.build.unix.snaps", false) + /** * Path to a zip file containing 'production' and 'test' directories with compiled classes of the project modules inside. */ diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy index f2505eeb48fa..5b824b3d03a3 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/LinuxDistributionCustomizer.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,12 @@ abstract class LinuxDistributionCustomizer { */ boolean buildTarGzWithoutBundledJre = true + /** + * If a .snap package should be produced + */ + String snapName = null + String snapDescription = null + /** * Name of the root directory inside linux .tar.gz archive */ diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy index e7209670c0af..e34feb20fd26 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/LinuxDistributionBuilder.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package org.jetbrains.intellij.build.impl +import com.intellij.openapi.util.text.StringUtil import org.jetbrains.intellij.build.BuildContext import org.jetbrains.intellij.build.BuildOptions import org.jetbrains.intellij.build.JvmArchitecture @@ -71,6 +72,7 @@ class LinuxDistributionBuilder extends OsSpecificDistributionBuilder { def jreDirectoryPath = buildContext.bundledJreManager.extractLinuxJre() if (jreDirectoryPath != null) { buildTarGz(jreDirectoryPath, osSpecificDistPath) + buildSnapPackage(jreDirectoryPath, osSpecificDistPath) } else { buildContext.messages.info("Skipping building Linux distribution with bundled JRE because JRE archive is missing") @@ -182,4 +184,86 @@ class LinuxDistributionBuilder extends OsSpecificDistributionBuilder { buildContext.notifyArtifactBuilt(gzPath) } } + + private void buildSnapPackage(String jreDirectoryPath, String unixDistPath) { + if (!buildContext.options.buildUnixSnaps || customizer.snapName == null) return + + if (StringUtil.isEmpty(customizer.iconPngPath)) buildContext.messages.error("'iconPngPath' not set") + if (StringUtil.isEmpty(customizer.snapDescription)) buildContext.messages.error("'snapDescription' not set") + + String snapDir = "${buildContext.paths.buildOutputRoot}/dist.snap" + + buildContext.messages.block("Build Linux .snap package") { + buildContext.messages.progress("Preparing files") + + def desktopTemplate = "${buildContext.paths.communityHome}/platform/platform-resources/src/entry.desktop" + def ce = buildContext.productProperties.productCode in ["IC", "PC"] + def productName = buildContext.applicationInfo.productName + if (ce && !productName.contains("Community Edition")) productName += " Community Edition" // IdeaApplicationInfo.xml//names@product + buildContext.ant.copy(file: desktopTemplate, tofile: "${snapDir}/snap/gui/${customizer.snapName}.desktop") { + filterset(begintoken: '$', endtoken: '$') { + filter(token: "NAME", value: productName) + filter(token: "ICON", value: "/bin/${buildContext.productProperties.baseFileName}.png") + filter(token: "SCRIPT", value: "/bin/${buildContext.productProperties.baseFileName}.sh") + filter(token: "WM_CLASS", value: "jetbrains-${buildContext.applicationInfo.shortProductName.toLowerCase()}${ce ? "-ce" : ""}") + } + } + + buildContext.ant.copy(file: customizer.iconPngPath, tofile: "${snapDir}/${customizer.snapName}.png") + + def snapcraftTemplate = "${buildContext.paths.communityHome}/build/snap/snapcraft-template.yaml" + def version = "${buildContext.applicationInfo.majorVersion}.${buildContext.applicationInfo.minorVersion}" + buildContext.ant.copy(file: snapcraftTemplate, tofile: "${snapDir}/snapcraft.yaml") { + filterset(begintoken: '$', endtoken: '$') { + filter(token: "NAME", value: customizer.snapName) + filter(token: "VERSION", value: version) + filter(token: "SUMMARY", value: productName) + filter(token: "DESCRIPTION", value: customizer.snapDescription) + filter(token: "SCRIPT", value: "bin/${buildContext.productProperties.baseFileName}.sh") + } + } + + buildContext.ant.concat(destfile: "${unixDistPath}/bin/idea.properties", append: true) { + filelist(dir: "${buildContext.paths.communityHome}/build/snap", files: "idea-snap.properties") + } + + buildContext.ant.delete(quiet: true) { + fileset(dir: "${unixDistPath}/bin") { + include(name: "fsnotifier") + include(name: "fsnotifier-arm") + include(name: "libyjpagent-linux.so") + } + } + + buildContext.ant.chmod(perm: "755") { + fileset(dir: unixDistPath) { + include(name: "bin/*.sh") + include(name: "bin/*.py") + include(name: "bin/fsnotifier*") + customizer.extraExecutables.each { include(name: it) } + } + fileset(dir: jreDirectoryPath) { + include(name: "jre64/bin/*") + } + } + + buildContext.messages.progress("Building package") + + buildContext.ant.exec(executable: "docker", dir: snapDir, failonerror: true) { + arg(value: "run") + arg(value: "--volume=${snapDir}:/build") + arg(value: "--volume=${buildContext.paths.distAll}:/build/dist.all:ro") + arg(value: "--volume=${unixDistPath}:/build/dist.unix:ro") + arg(value: "--volume=${jreDirectoryPath}:/build/jre:ro") + arg(value: "--workdir=/build") + arg(value: "--env=SNAPCRAFT_SETUP_CORE=1") + arg(value: "snapcore/snapcraft") + arg(value: "snapcraft") + } + + def snapArtifact = "${customizer.snapName}_${version}_amd64.snap" + buildContext.ant.move(file: "${snapDir}/${snapArtifact}", todir: buildContext.paths.artifacts) + buildContext.notifyArtifactBuilt("${buildContext.paths.artifacts}/" + snapArtifact) + } + } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java index 914cc3e3826e..0cf54e97fbf1 100644 --- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java @@ -66,6 +66,7 @@ import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED; public class AppUIUtil { private static final String VENDOR_PREFIX = "jetbrains-"; private static final boolean DEBUG_MODE = SystemProperties.getBooleanProperty("idea.debug.mode", false); + private static boolean ourMacDocIconSet = false; public static void updateWindowIcon(@NotNull Window window) { ApplicationInfoEx appInfo = ApplicationInfoImpl.getShadowInstance(); @@ -95,8 +96,9 @@ public class AppUIUtil { if (!SystemInfo.isMac) { window.setIconImages(images); } - else if (DEBUG_MODE) { + else if (DEBUG_MODE && !ourMacDocIconSet) { MacAppIcon.setDockIcon(ImageUtil.toBufferedImage(images.get(0))); + ourMacDocIconSet = true; } } } diff --git a/python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy b/python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy index 059e48c073c5..e7a701d402f0 100644 --- a/python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy +++ b/python/build/groovy/org/jetbrains/intellij/build/pycharm/PyCharmCommunityProperties.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +78,12 @@ class PyCharmCommunityProperties extends PyCharmPropertiesBase { return new LinuxDistributionCustomizer() { { iconPngPath = "$projectHome/python/resources/PyCharmCore128.png" + //snapName = "pycharm-community" + //snapDescription = + // "Python IDE for professional developers. Save time while PyCharm takes care of the routine. " + // "Focus on bigger things and embrace the keyboard-centric approach to get the most of PyCharm’s many productivity features." } + @Override String getRootDirectoryName(ApplicationInfoProperties applicationInfo, String buildNumber) { "pycharm-community-${applicationInfo.isEAP ? buildNumber : applicationInfo.fullVersion}" diff --git a/python/helpers/pycharm/_jb_runner_tools.py b/python/helpers/pycharm/_jb_runner_tools.py index 0b3089241f72..9588590009f8 100644 --- a/python/helpers/pycharm/_jb_runner_tools.py +++ b/python/helpers/pycharm/_jb_runner_tools.py @@ -18,7 +18,7 @@ if teamcity_presence_env_var not in os.environ: # anything sent to stdout/stderr goes to IDE directly, not after test is over like it is done by default. # out and err are not in sync, so output may go to wrong test JB_DISABLE_BUFFERING = "JB_DISABLE_BUFFERING" in os.environ - +PROJECT_DIR = os.getcwd() def _parse_parametrized(part): """ @@ -179,7 +179,7 @@ class NewTeamcityServiceMessages(_old_service_messages): loc = possible_location.find("(") if loc > 0: possible_location = possible_location[:loc].strip() - properties["locationHint"] = "python<{0}>://{1}".format(os.getcwd(), possible_location) + properties["locationHint"] = "python<{0}>://{1}".format(PROJECT_DIR, possible_location) except KeyError: # If message does not have name, then it is not test # Simply pass it @@ -399,4 +399,4 @@ def jb_doc_args(framework_name, args): Runner encouraged to report its arguments to user with aid of this function """ - print("Launching {0} with arguments {1} in {2}\n".format(framework_name, " ".join(args), os.getcwd())) + print("Launching {0} with arguments {1} in {2}\n".format(framework_name, " ".join(args), PROJECT_DIR)) diff --git a/python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml b/python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml index 6acf8f4597cd..7184297f721c 100644 --- a/python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml +++ b/python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml @@ -1,7 +1,7 @@ - +