Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2017-10-05 19:19:30 +02:00
66 changed files with 744 additions and 412 deletions
+1 -1
View File
@@ -761,7 +761,7 @@
<constraint name="s" nameOfExprType="java.lang.String" exprTypeWithinHierarchy="true" within="" contains="" />
<constraint name="c" nameOfExprType="char" exprTypeWithinHierarchy="true" within="" contains="" />
</replaceConfiguration>
<replaceConfiguration name="TokenSet.create(TokenType.WHITE_SPACE) -&gt; TokenSet.WS" text="com.intellij.psi.tree.TokenSet.create(com.intellij.psi.TokenType.WHITE_SPACE)" recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.intellij.psi.tree.TokenSet.WS" />
<replaceConfiguration name="TokenSet.create(TokenType.WHITE_SPACE) -&gt; TokenSet.WHITE_SPACE" text="com.intellij.psi.tree.TokenSet.create(com.intellij.psi.TokenType.WHITE_SPACE)" recursive="false" caseInsensitive="true" type="JAVA" reformatAccordingToStyle="true" shortenFQN="true" replacement="com.intellij.psi.tree.TokenSet.WHITE_SPACE" />
</inspection_tool>
<inspection_tool class="SafeVarargsDetector" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="SeamAnnotationIncorrectSignatureInspection" enabled="false" level="ERROR" enabled_by_default="false" />
@@ -22,8 +22,6 @@ public class CaptureAgent {
private static Instrumentation ourInstrumentation;
private static boolean DEBUG = false;
static final KeyProvider THIS_KEY_PROVIDER = new ParamKeyProvider(0);
private static Map<String, List<CapturePoint>> myCapturePoints = new HashMap<String, List<CapturePoint>>();
private static Map<String, List<InsertPoint>> myInsertPoints = new HashMap<String, List<InsertPoint>>();
@@ -177,7 +175,7 @@ public class CaptureAgent {
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
public MethodVisitor visitMethod(final int access, String name, final String desc, String signature, String[] exceptions) {
if ((access & Opcodes.ACC_BRIDGE) == 0) {
for (final CapturePoint capturePoint : myCapturePoints) {
if (capturePoint.myMethodName.equals(name)) {
@@ -188,7 +186,7 @@ public class CaptureAgent {
return new MethodVisitor(api, super.visitMethod(access, name, desc, signature, exceptions)) {
@Override
public void visitCode() {
capturePoint.myKeyProvider.loadKey(mv);
capturePoint.myKeyProvider.loadKey(mv, (access & Opcodes.ACC_STATIC) != 0, Type.getMethodType(desc).getArgumentTypes());
visitMethodInsn(Opcodes.INVOKESTATIC, CaptureStorage.class.getName().replaceAll("\\.", "/"), "capture", "(Ljava/lang/Object;)V", false);
super.visitCode();
}
@@ -221,24 +219,28 @@ public class CaptureAgent {
Label start = new Label();
mv.visitLabel(start);
insertEnter(mv, insertPoint);
boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
Type[] argumentTypes = Type.getMethodType(desc).getArgumentTypes();
insertEnter(mv, insertPoint, isStatic, argumentTypes);
// this
mv.visitVarInsn(Opcodes.ALOAD, 0);
// params
int index = (access & Opcodes.ACC_STATIC) == 0 ? 1 : 0;
for (Type t : Type.getMethodType(desc).getArgumentTypes()) {
int index = isStatic ? 0 : 1;
for (Type t : argumentTypes) {
mv.visitVarInsn(t.getOpcode(Opcodes.ILOAD), index);
index += t.getSize();
}
// original call
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, insertPoint.myClassName, getNewName(insertPoint.myMethodName), desc, false);
mv.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKESPECIAL,
insertPoint.myClassName, getNewName(insertPoint.myMethodName), desc, false);
Label end = new Label();
mv.visitLabel(end);
// regular exit
insertExit(mv, insertPoint);
insertExit(mv, insertPoint, isStatic, argumentTypes);
mv.visitInsn(Type.getReturnType(desc).getOpcode(Opcodes.IRETURN));
Label catchLabel = new Label();
@@ -246,21 +248,21 @@ public class CaptureAgent {
mv.visitTryCatchBlock(start, end, catchLabel, null);
// exception exit
insertExit(mv, insertPoint);
insertExit(mv, insertPoint, isStatic, argumentTypes);
mv.visitInsn(Opcodes.ATHROW);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
private static void insertEnter(MethodVisitor mv, InsertPoint insertPoint) {
insertPoint.myKeyProvider.loadKey(mv);
private static void insertEnter(MethodVisitor mv, InsertPoint insertPoint, boolean isStatic, Type[] argumentTypes) {
insertPoint.myKeyProvider.loadKey(mv, isStatic, argumentTypes);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, CaptureStorage.class.getName().replaceAll("\\.", "/"), "insertEnter",
"(Ljava/lang/Object;)V", false);
}
private static void insertExit(MethodVisitor mv, InsertPoint insertPoint) {
insertPoint.myKeyProvider.loadKey(mv);
private static void insertExit(MethodVisitor mv, InsertPoint insertPoint, boolean isStatic, Type[] argumentTypes) {
insertPoint.myKeyProvider.loadKey(mv, isStatic, argumentTypes);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, CaptureStorage.class.getName().replaceAll("\\.", "/"), "insertExit",
"(Ljava/lang/Object;)V", false);
}
@@ -350,6 +352,13 @@ public class CaptureAgent {
points.add(new InsertPoint(className, methodName, keyProvider));
}
static final KeyProvider THIS_KEY_PROVIDER = new KeyProvider() {
@Override
public void loadKey(MethodVisitor mv, boolean isStatic, Type[] argumentTypes) {
mv.visitVarInsn(Opcodes.ALOAD, 0);
}
};
private static KeyProvider createKeyProvider(String[] line) {
if ("this".equals(line[0])) {
return THIS_KEY_PROVIDER;
@@ -363,7 +372,7 @@ public class CaptureAgent {
}
private interface KeyProvider {
void loadKey(MethodVisitor mv);
void loadKey(MethodVisitor mv, boolean isStatic, Type[] argumentTypes);
}
private static class FieldKeyProvider implements KeyProvider {
@@ -378,22 +387,26 @@ public class CaptureAgent {
}
@Override
public void loadKey(MethodVisitor mv) {
public void loadKey(MethodVisitor mv, boolean isStatic, Type[] argumentTypes) {
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, myClassName, myFieldName, myFieldDesc);
}
}
private static class ParamKeyProvider implements KeyProvider {
int mySlot;
int myIdx;
public ParamKeyProvider(int slot) {
mySlot = slot;
public ParamKeyProvider(int idx) {
myIdx = idx;
}
@Override
public void loadKey(MethodVisitor mv) {
mv.visitVarInsn(Opcodes.ALOAD, mySlot);
public void loadKey(MethodVisitor mv, boolean isStatic, Type[] argumentTypes) {
int index = isStatic ? 0 : 1;
for (int i = 0; i < myIdx; i++) {
index += argumentTypes[i].getSize();
}
mv.visitVarInsn(Opcodes.ALOAD, index);
}
}
}
@@ -66,6 +66,12 @@ public class CaptureConfigurable implements SearchableConfigurable {
@NotNull
@Override
public String getId() {
return getHelpTopic();
}
@NotNull
@Override
public String getHelpTopic() {
return "reference.idesettings.debugger.capture";
}
@@ -17,59 +17,64 @@ public class CaptureSettingsProvider {
private static final List<CapturePoint> IDE_INSERT_POINTS;
private static final KeyProvider THIS_KEY = new StringKeyProvider("this");
private static final KeyProvider FIRST_PARAM = param(0);
static {
CAPTURE_POINTS.add(new AgentCapturePoint("javax/swing/SwingUtilities", "invokeLater", new StringKeyProvider("0")));
INSERT_POINTS.add(new AgentInsertPoint("java/awt/event/InvocationEvent", "dispatch",
new FieldKeyProvider("java/awt/event/InvocationEvent", "runnable", "Ljava/lang/Runnable;")));
addCapture("javax/swing/SwingUtilities", "invokeLater", FIRST_PARAM);
addInsert("java/awt/event/InvocationEvent",
"dispatch",
new FieldKeyProvider("java/awt/event/InvocationEvent", "runnable", "Ljava/lang/Runnable;"));
CAPTURE_POINTS.add(new AgentCapturePoint("java/lang/Thread", "start", THIS_KEY));
INSERT_POINTS.add(new AgentInsertPoint("java/lang/Thread", "run", THIS_KEY));
addCapture("java/lang/Thread", "start", THIS_KEY);
addInsert("java/lang/Thread", "run", THIS_KEY);
CAPTURE_POINTS.add(new AgentCapturePoint("java/util/concurrent/ExecutorService", "submit", new StringKeyProvider("1")));
INSERT_POINTS.add(new AgentInsertPoint("java/util/concurrent/Executors$RunnableAdapter", "call",
new FieldKeyProvider("java/util/concurrent/Executors$RunnableAdapter",
"task",
"Ljava/lang/Runnable;")));
addCapture("java/util/concurrent/ExecutorService", "submit", FIRST_PARAM);
addInsert("java/util/concurrent/Executors$RunnableAdapter",
"call",
new FieldKeyProvider("java/util/concurrent/Executors$RunnableAdapter",
"task",
"Ljava/lang/Runnable;"));
CAPTURE_POINTS.add(new AgentCapturePoint("java/util/concurrent/ThreadPoolExecutor", "execute", new StringKeyProvider("1")));
INSERT_POINTS.add(new AgentInsertPoint("java/util/concurrent/FutureTask", "run", THIS_KEY));
addCapture("java/util/concurrent/ThreadPoolExecutor", "execute", FIRST_PARAM);
addInsert("java/util/concurrent/FutureTask", "run", THIS_KEY);
CAPTURE_POINTS.add(new AgentCapturePoint("java/util/concurrent/CompletableFuture", "supplyAsync", new StringKeyProvider("0")));
addCapture("java/util/concurrent/CompletableFuture", "supplyAsync", FIRST_PARAM);
AgentInsertPoint point = new AgentInsertPoint("java/util/concurrent/CompletableFuture$AsyncSupply",
"run",
new FieldKeyProvider("java/util/concurrent/CompletableFuture$AsyncSupply",
"fn",
"Ljava/util/function/Supplier;"));
point.myInsertPoint.myInsertMethodName = "run$$$capture";
point.myInsertPoint.myInsertKeyExpression = "f";
INSERT_POINTS.add(point);
CapturePoint ideInsertPoint = new CapturePoint();
ideInsertPoint.myInsertClassName = "java.util.concurrent.CompletableFuture$AsyncSupply";
ideInsertPoint.myInsertMethodName = "run$$$capture";
ideInsertPoint.myInsertKeyExpression = "f";
INSERT_POINTS.add(new AgentInsertPoint("java/util/concurrent/CompletableFuture$AsyncSupply", "run",
new FieldKeyProvider("java/util/concurrent/CompletableFuture$AsyncSupply",
"fn",
"Ljava/util/function/Supplier;"),
ideInsertPoint));
addCapture("java/util/concurrent/CompletableFuture", "runAsync", FIRST_PARAM);
point = new AgentInsertPoint("java/util/concurrent/CompletableFuture$AsyncRun",
"run",
new FieldKeyProvider("java/util/concurrent/CompletableFuture$AsyncRun",
"fn",
"Ljava/lang/Runnable;"));
point.myInsertPoint.myInsertMethodName = "run$$$capture";
point.myInsertPoint.myInsertKeyExpression = "f";
INSERT_POINTS.add(point);
CAPTURE_POINTS.add(new AgentCapturePoint("java/util/concurrent/CompletableFuture", "runAsync", new StringKeyProvider("0")));
ideInsertPoint = new CapturePoint();
ideInsertPoint.myInsertClassName = "java.util.concurrent.CompletableFuture$AsyncRun";
ideInsertPoint.myInsertMethodName = "run$$$capture";
ideInsertPoint.myInsertKeyExpression = "f";
INSERT_POINTS.add(new AgentInsertPoint("java/util/concurrent/CompletableFuture$AsyncRun",
"run",
new FieldKeyProvider("java/util/concurrent/CompletableFuture$AsyncRun",
"fn",
"Ljava/lang/Runnable;"),
ideInsertPoint));
addCapture("java/util/concurrent/CompletableFuture", "thenAcceptAsync", FIRST_PARAM);
addInsert("java/util/concurrent/CompletableFuture$UniAccept",
"tryFire",
new FieldKeyProvider("java/util/concurrent/CompletableFuture$UniAccept",
"fn",
"Ljava/util/function/Consumer;"));
CAPTURE_POINTS.add(new AgentCapturePoint("java/util/concurrent/CompletableFuture", "thenAcceptAsync", new StringKeyProvider("1")));
INSERT_POINTS.add(new AgentInsertPoint("java/util/concurrent/CompletableFuture$UniAccept", "tryFire",
new FieldKeyProvider("java/util/concurrent/CompletableFuture$UniAccept",
"fn",
"Ljava/util/function/Consumer;")));
addCapture("java/util/concurrent/CompletableFuture", "thenRunAsync", FIRST_PARAM);
addInsert("java/util/concurrent/CompletableFuture$UniRun",
"tryFire",
new FieldKeyProvider("java/util/concurrent/CompletableFuture$UniRun",
"fn",
"Ljava/lang/Runnable;"));
CAPTURE_POINTS.add(new AgentCapturePoint("java/util/concurrent/CompletableFuture", "thenRunAsync", new StringKeyProvider("1")));
INSERT_POINTS.add(new AgentInsertPoint("java/util/concurrent/CompletableFuture$UniRun", "tryFire",
new FieldKeyProvider("java/util/concurrent/CompletableFuture$UniRun",
"fn",
"Ljava/lang/Runnable;")));
// netty
addCapture("io/netty/util/concurrent/SingleThreadEventExecutor", "addTask", FIRST_PARAM);
addInsert("io/netty/util/concurrent/AbstractEventExecutor", "safeExecute", FIRST_PARAM);
IDE_INSERT_POINTS = StreamEx.of(INSERT_POINTS).map(p -> p.myInsertPoint).nonNull().toList();
}
@@ -127,16 +132,15 @@ public class CaptureSettingsProvider {
}
}
}
public AgentInsertPoint(String className, String methodName, KeyProvider key, CapturePoint point) {
super(className, methodName, key);
this.myInsertPoint = point;
}
}
public interface KeyProvider {
String asString();
}
private static KeyProvider param(int idx) {
return new StringKeyProvider(Integer.toString(idx));
}
private static class StringKeyProvider implements KeyProvider {
private final String myValue;
@@ -167,4 +171,12 @@ public class CaptureSettingsProvider {
return myClassName + AgentPoint.SEPARATOR + myFieldName + AgentPoint.SEPARATOR + myFieldDesc;
}
}
private static void addCapture(String className, String methodName, KeyProvider key) {
CAPTURE_POINTS.add(new AgentCapturePoint(className, methodName, key));
}
private static void addInsert(String className, String methodName, KeyProvider key) {
INSERT_POINTS.add(new AgentInsertPoint(className, methodName, key));
}
}
@@ -1,18 +1,4 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.settings;
import com.intellij.debugger.DebuggerBundle;
@@ -315,7 +301,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable {
@Override
@NotNull
public String getHelpTopic() {
return "reference.idesettings.debugger.dataviews";
return "Debugger_Data_Views_Java";
}
@Override
@@ -19,6 +19,7 @@ import com.intellij.ExtensionPoints;
import com.intellij.debugger.impl.GenericDebuggerRunnerSettings;
import com.intellij.diagnostic.logging.OutputFileUtil;
import com.intellij.execution.configurations.*;
import com.intellij.execution.filters.ArgumentFileFilter;
import com.intellij.execution.impl.ConsoleBuffer;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessAdapter;
@@ -66,10 +67,7 @@ import org.jetbrains.jps.model.serialization.PathMacroUtil;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.*;
public abstract class JavaTestFrameworkRunnableState<T extends
ModuleBasedConfiguration<JavaRunConfigurationModule>
@@ -82,6 +80,7 @@ public abstract class JavaTestFrameworkRunnableState<T extends
protected File myWorkingDirsFile = null;
private RemoteConnectionCreator remoteConnectionCreator;
private final List<ArgumentFileFilter> myArgumentFileFilters = new ArrayList<>();
public void setRemoteConnectionCreator(RemoteConnectionCreator remoteConnectionCreator) {
this.remoteConnectionCreator = remoteConnectionCreator;
@@ -128,6 +127,16 @@ public abstract class JavaTestFrameworkRunnableState<T extends
return false;
}
@Override
protected GeneralCommandLine createCommandLine() throws ExecutionException {
GeneralCommandLine commandLine = super.createCommandLine();
Map<String, String> content = commandLine.getUserData(JdkUtil.COMMAND_LINE_CONTENT);
if (content != null) {
content.forEach((key, value) -> myArgumentFileFilters.add(new ArgumentFileFilter(key, value)));
}
return commandLine;
}
@NotNull
@Override
public ExecutionResult execute(@NotNull Executor executor, @NotNull ProgramRunner runner) throws ExecutionException {
@@ -143,6 +152,10 @@ public abstract class JavaTestFrameworkRunnableState<T extends
final OSProcessHandler handler = createHandler(executor);
for (ArgumentFileFilter filter : myArgumentFileFilters) {
consoleView.addMessageFilter(filter);
}
consoleView.attachToProcess(handler);
final AbstractTestProxy root = viewer.getRoot();
if (root instanceof TestProxyRoot) {
@@ -21,6 +21,7 @@ import com.intellij.diagnostic.logging.LogConfigurationPanel;
import com.intellij.execution.*;
import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.execution.configurations.*;
import com.intellij.execution.filters.ArgumentFileFilter;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.junit.RefactoringListeners;
import com.intellij.execution.process.KillableProcessHandler;
@@ -34,6 +35,7 @@ import com.intellij.openapi.options.SettingsEditorGroup;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.JdkUtil;
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.psi.PsiClass;
@@ -307,6 +309,16 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
return params;
}
@Override
protected GeneralCommandLine createCommandLine() throws ExecutionException {
GeneralCommandLine line = super.createCommandLine();
Map<String, String> content = line.getUserData(JdkUtil.COMMAND_LINE_CONTENT);
if (content != null) {
content.forEach((key, value) -> addConsoleFilters(new ArgumentFileFilter(key, value)));
}
return line;
}
@NotNull
@Override
protected OSProcessHandler startProcess() throws ExecutionException {
@@ -197,7 +197,7 @@ public class ModuleNameLocationComponent {
VirtualFile baseDir = project.getBaseDir();
if (baseDir != null) { //e.g. was deleted
final String baseDirPath = baseDir.getPath();
String moduleName = ProjectWizardUtil.findNonExistingFileName(baseDirPath, "untitled", "");
String moduleName = ProjectWizardUtil.findNonExistingFileName(baseDirPath, myWizardContext.getDefaultModuleName(), "");
String contentRoot = baseDirPath + "/" + moduleName;
if (!Comparing.strEqual(project.getName(), myWizardContext.getProjectName()) &&
!myWizardContext.isCreatingNewProject() &&
@@ -39,8 +39,9 @@ public class NewProjectWizard extends AbstractProjectWizard {
init(modulesProvider);
}
public NewProjectWizard(Project project, Component dialogParent, ModulesProvider modulesProvider) {
public NewProjectWizard(Project project, Component dialogParent, ModulesProvider modulesProvider, String defaultModuleName) {
super(IdeBundle.message("title.add.module"), project, dialogParent);
myWizardContext.setDefaultModuleName(defaultModuleName);
init(modulesProvider);
}
@@ -370,9 +370,9 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
@Nullable
public List<Module> addModule(Component parent, boolean anImport) {
public List<Module> addModule(Component parent, boolean anImport, String defaultModuleName) {
if (myProject.isDefault()) return null;
final ProjectBuilder builder = runModuleWizard(parent, anImport);
final ProjectBuilder builder = runModuleWizard(parent, anImport, defaultModuleName);
if (builder != null ) {
final List<Module> modules = new ArrayList<>();
final List<Module> committedModules;
@@ -426,7 +426,7 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
}
@Nullable
ProjectBuilder runModuleWizard(Component dialogParent, boolean anImport) {
private ProjectBuilder runModuleWizard(Component dialogParent, boolean anImport, String defaultModuleName) {
AbstractProjectWizard wizard;
if (anImport) {
wizard = ImportModuleAction.selectFileAndCreateWizard(myProject, dialogParent);
@@ -438,7 +438,7 @@ public class ModulesConfigurator implements ModulesProvider, ModuleEditor.Change
}
}
else {
wizard = new NewProjectWizard(myProject, dialogParent, this);
wizard = new NewProjectWizard(myProject, dialogParent, this, defaultModuleName);
}
if (!wizard.showAndGet()) {
return null;
@@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleGrouperKt;
import com.intellij.openapi.module.impl.ModuleManagerImpl;
/**
@@ -47,9 +48,11 @@ public class NewModuleInGroupAction extends NewModuleAction {
@Override
protected void processCreatedModule(final Module module, final Object dataFromContext) {
ModuleGroup group = (ModuleGroup) dataFromContext;
if (group != null) {
ModuleManagerImpl.getInstanceImpl(module.getProject()).setModuleGroupPath(module, group.getGroupPath());
if (!ModuleGrouperKt.isQualifiedModuleNamesEnabled(module.getProject())) {
ModuleGroup group = (ModuleGroup) dataFromContext;
if (group != null) {
ModuleManagerImpl.getInstanceImpl(module.getProject()).setModuleGroupPath(module, group.getGroupPath());
}
}
}
}
@@ -541,8 +541,8 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
return myContext.myModulesConfigurator.getFacetsConfigurator();
}
private void addModule(boolean anImport) {
final List<Module> modules = myContext.myModulesConfigurator.addModule(myTree, anImport);
private void addModule(boolean anImport, String defaultModuleName) {
final List<Module> modules = myContext.myModulesConfigurator.addModule(myTree, anImport, defaultModuleName);
if (modules != null) {
for (Module module : modules) {
addModuleNode(module);
@@ -1006,7 +1006,15 @@ public class ModuleStructureConfigurable extends BaseStructureConfigurable imple
@Override
public void actionPerformed(final AnActionEvent e) {
addModule(myImport);
String defaultModuleName = "untitled";
MyNode selectedNode = getSelectedNode();
if (ModuleGrouperKt.isQualifiedModuleNamesEnabled(myProject) && selectedNode instanceof ModuleGroupNodeImpl) {
ModuleGroup group = ((ModuleGroupNode)selectedNode).getModuleGroup();
if (group != null && !group.getGroupPathList().isEmpty()) {
defaultModuleName = StringUtil.join(group.getGroupPathList(), ".") + ".untitled";
}
}
addModule(myImport, defaultModuleName);
}
}
@@ -304,7 +304,7 @@ public class CodeInsightUtil {
if (baseClass.hasModifierProperty(PsiModifier.FINAL)) return;
if (matcher.getPrefix().length() > 2) {
JBTreeTraverser<PsiClass> traverser = new JBTreeTraverser<>(c -> Arrays.asList(c.getInnerClasses()));
JBTreeTraverser<PsiClass> traverser = JBTreeTraverser.of(PsiClass::getInnerClasses);
AllClassesGetter.processJavaClasses(matcher, context.getProject(), scope, psiClass -> {
Iterable<PsiClass> inheritors = traverser.withRoot(psiClass).filter(c -> c.isInheritor(baseClass, true));
return ContainerUtil.process(inheritors, inheritorsProcessor);
@@ -1,18 +1,4 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.lang.java.parser;
import com.intellij.lang.PsiBuilder;
@@ -26,6 +12,10 @@ import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
import static com.intellij.util.containers.ContainerUtil.newTroveSet;
public class JavadocParser {
private static final TokenSet TAG_VALUES_SET = TokenSet.create(
JavaDocTokenType.DOC_TAG_VALUE_TOKEN, JavaDocTokenType.DOC_TAG_VALUE_COMMA, JavaDocTokenType.DOC_TAG_VALUE_DOT,
@@ -40,10 +30,9 @@ public class JavadocParser {
private static final String SEE_TAG = "@see";
private static final String LINK_TAG = "@link";
private static final String LINK_PLAIN_TAG = "@linkplain";
private static final String THROWS_TAG = "@throws";
private static final String EXCEPTION_TAG = "@exception";
private static final String PARAM_TAG = "@param";
private static final String VALUE_TAG = "@value";
private static final Set<String> REFERENCE_TAGS = newTroveSet("@throws", "@exception", "@provides", "@uses");
private static Key<Integer> BRACE_SCOPE_KEY = Key.create("Javadoc.Parser.Brace.Scope");
@@ -139,7 +128,7 @@ public class JavadocParser {
JavaParserUtil.getLanguageLevel(builder).isAtLeast(LanguageLevel.JDK_1_4) && LINK_PLAIN_TAG.equals(tagName) && isInline) {
parseSeeTagValue(builder, false);
}
else if (!isInline && (THROWS_TAG.equals(tagName) || EXCEPTION_TAG.equals(tagName))) {
else if (!isInline && REFERENCE_TAGS.contains(tagName)) {
PsiBuilder.Marker tagValue = builder.mark();
builder.remapCurrentToken(JavaDocElementType.DOC_REFERENCE_HOLDER);
builder.advanceLexer();
@@ -0,0 +1,4 @@
/**
* @provides java.nio.file.FileSystem just for fun
*/
class Test {}
@@ -0,0 +1,52 @@
PsiJavaFile:ProvidesTag.java
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_START('/**')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('*')
PsiDocToken:DOC_COMMENT_DATA(' ')
PsiDocTag:@provides
PsiDocToken:DOC_TAG_NAME('@provides')
PsiWhiteSpace(' ')
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_REFERENCE_HOLDER)
PsiJavaCodeReferenceElement:java.nio.file.FileSystem
PsiJavaCodeReferenceElement:java.nio.file
PsiJavaCodeReferenceElement:java.nio
PsiJavaCodeReferenceElement:java
PsiIdentifier:java('java')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:nio('nio')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:file('file')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:FileSystem('FileSystem')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiDocToken:DOC_COMMENT_DATA('just for fun')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_END('*/')
PsiWhiteSpace('\n')
PsiModifierList:
<empty list>
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,4 @@
/**
* @throws E an exception
*/
class Test {}
@@ -0,0 +1,37 @@
PsiJavaFile:ThrowsTag.java
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_START('/**')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('*')
PsiDocToken:DOC_COMMENT_DATA(' ')
PsiDocTag:@throws
PsiDocToken:DOC_TAG_NAME('@throws')
PsiWhiteSpace(' ')
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_REFERENCE_HOLDER)
PsiJavaCodeReferenceElement:E
PsiIdentifier:E('E')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiDocToken:DOC_COMMENT_DATA('an exception')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_END('*/')
PsiWhiteSpace('\n')
PsiModifierList:
<empty list>
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,4 @@
/**
* @uses java.nio.file.FileSystem because it can
*/
class Test {}
@@ -0,0 +1,52 @@
PsiJavaFile:UsesTag.java
PsiImportList
<empty list>
PsiClass:Test
PsiDocComment
PsiDocToken:DOC_COMMENT_START('/**')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_LEADING_ASTERISKS('*')
PsiDocToken:DOC_COMMENT_DATA(' ')
PsiDocTag:@uses
PsiDocToken:DOC_TAG_NAME('@uses')
PsiWhiteSpace(' ')
PsiElement(DOC_TAG_VALUE_ELEMENT)
PsiElement(DOC_REFERENCE_HOLDER)
PsiJavaCodeReferenceElement:java.nio.file.FileSystem
PsiJavaCodeReferenceElement:java.nio.file
PsiJavaCodeReferenceElement:java.nio
PsiJavaCodeReferenceElement:java
PsiIdentifier:java('java')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:nio('nio')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:file('file')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiIdentifier:FileSystem('FileSystem')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiDocToken:DOC_COMMENT_DATA('because it can')
PsiWhiteSpace('\n ')
PsiDocToken:DOC_COMMENT_END('*/')
PsiWhiteSpace('\n')
PsiModifierList:
<empty list>
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Test('Test')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -123,10 +123,10 @@ public class CompilerReferencesTest extends CompilerReferencesTestBase {
}
public void testExtensionRename() {
final PsiFile file = myFixture.configureByFiles(getName() + "/Bar.java", getName() + "/Foo.txt")[1];
VirtualFile file = myFixture.configureByFiles(getName() + "/Bar.java", getName() + "/Foo.txt")[1].getVirtualFile();
rebuildProject();
assertOneElement(getReferentFilesForElementUnderCaret());
myFixture.renameElement(file, "Foo.java");
myFixture.renameElement(getPsiManager().findFile(file), "Foo.java");
final PsiClass foo = myFixture.findClass("Foo");
assertNotNull(foo);
final CompilerReferenceServiceImpl compilerReferenceService = (CompilerReferenceServiceImpl) CompilerReferenceService
@@ -136,10 +136,10 @@ public class CompilerReferencesTest extends CompilerReferencesTestBase {
}
public void testReverseExtensionRename() {
final PsiFile file = myFixture.configureByFiles(getName() + "/Bar.java", getName() + "/Foo.java")[1];
VirtualFile file = myFixture.configureByFiles(getName() + "/Bar.java", getName() + "/Foo.java")[1].getVirtualFile();
rebuildProject();
assertSize(2, getReferentFilesForElementUnderCaret());
myFixture.renameElement(file, "Foo.txt");
myFixture.renameElement(getPsiManager().findFile(file), "Foo.txt");
assertEquals("Bar.java", assertOneElement(getReferentFilesForElementUnderCaret()).getName());
}
@@ -1,18 +1,4 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.parser;
public class JavadocParsingTest extends JavaParsingTestCase {
@@ -93,4 +79,8 @@ public class JavadocParsingTest extends JavaParsingTestCase {
public void testValueQualified() { doTest(true); }
public void testValueUnqualifiedWithHash() { doTest(true); }
public void testValueUnqualifiedWithoutHash() { doTest(true); }
public void testThrowsTag() { doTest(true); }
public void testUsesTag() { doTest(true); }
public void testProvidesTag() { doTest(true); }
}
@@ -10,11 +10,16 @@ import com.intellij.util.io.generateInVirtualTempDir
/**
* @author nik
*/
class ProjectViewStructureTest : BaseProjectViewTestCase() {
class ModulesInProjectViewTest : BaseProjectViewTestCase() {
init {
myPrintInfo = Queryable.PrintInfo()
}
override fun setUp() {
super.setUp()
myStructure.isShowLibraryContents = false
}
fun `test unloaded modules`() {
val root = directoryContent {
dir("loaded") {
@@ -34,7 +39,6 @@ class ProjectViewStructureTest : BaseProjectViewTestCase() {
PsiTestUtil.addContentRoot(createModule("unloaded-inner"), root.findFileByRelativePath("loaded/unloaded-inner"))
PsiTestUtil.addContentRoot(createModule("unloaded"), root.findChild("unloaded"))
PsiTestUtil.addContentRoot(createModule("loaded-inner"), root.findFileByRelativePath("unloaded/loaded-inner"))
myStructure.isShowLibraryContents = false
val expected = """
|Project
| loaded
@@ -61,22 +65,27 @@ class ProjectViewStructureTest : BaseProjectViewTestCase() {
fun `test unloaded module with qualified name`() {
val root = directoryContent {
dir("unloaded") {
dir("subdir") { }
dir("subdir") {}
file("y.txt")
}
dir("unloaded2") {
dir("subdir") {}
}
}.generateInVirtualTempDir()
PsiTestUtil.addContentRoot(createModule("foo.bar.unloaded"), root.findChild("unloaded"))
PsiTestUtil.addContentRoot(createModule("unloaded2"), root.findChild("unloaded2"))
myStructure.isShowLibraryContents = false
val expected = """
|Project
| Group: foo
| Group: bar
| unloaded
| subdir
| y.txt
| Group: foo.bar
| unloaded
| subdir
| y.txt
| foo.bar.unloaded.iml
| test unloaded module with qualified name.iml
| unloaded2
| subdir
| unloaded2.iml
|
""".trimMargin()
assertStructureEqual(expected)
@@ -85,5 +94,49 @@ class ProjectViewStructureTest : BaseProjectViewTestCase() {
assertStructureEqual(expected)
}
fun `test do not show parent groups for single module`() {
val root = directoryContent {
dir("module") {
dir("subdir") {}
}
}.generateInVirtualTempDir()
PsiTestUtil.addContentRoot(createModule("foo.bar.module"), root.findChild("module"))
assertStructureEqual("""
|Project
| foo.bar.module.iml
| module
| subdir
| test do not show parent groups for single module.iml
|
""".trimMargin())
}
fun `test modules with common parent group`() {
val root = directoryContent {
dir("module1") {
dir("subdir") {}
}
dir("module2") {
dir("subdir") {}
}
}.generateInVirtualTempDir()
PsiTestUtil.addContentRoot(createModule("foo.bar.module1"), root.findChild("module1"))
PsiTestUtil.addContentRoot(createModule("foo.baz.module2"), root.findChild("module2"))
assertStructureEqual("""
|Project
| Group: foo
| Group: bar
| module1
| subdir
| Group: baz
| module2
| subdir
| foo.bar.module1.iml
| foo.baz.module2.iml
| test modules with common parent group.iml
|
""".trimMargin())
}
override fun getTestPath() = null
}
@@ -15,7 +15,6 @@
*/
package com.jetbrains.jsonSchema.impl;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBTreeTraverser;
import org.jetbrains.annotations.NotNull;
@@ -34,24 +33,25 @@ public class MatchResult {
}
public static MatchResult create(@NotNull JsonSchemaTreeNode root) {
final List<JsonSchemaObject> schemas = new ArrayList<>();
final Map<Integer, Set<JsonSchemaObject>> oneOfGroups = new HashMap<>();
ContainerUtil.process(new JBTreeTraverser<JsonSchemaTreeNode>(node -> node.getChildren()).withRoot(root).preOrderDfsTraversal(),
node -> {
if (node.getChildren().isEmpty() && !node.isAny() && !node.isNothing() &&
SchemaResolveState.normal.equals(node.getResolveState())) {
final int groupNumber = node.getExcludingGroupNumber();
if (groupNumber < 0) {
schemas.add(node.getSchema());
}
else {
Set<JsonSchemaObject> set = oneOfGroups.get(groupNumber);
if (set == null) oneOfGroups.put(groupNumber, (set = new HashSet<>()));
set.add(node.getSchema());
}
}
return true;
});
List<JsonSchemaObject> schemas = new ArrayList<>();
Map<Integer, Set<JsonSchemaObject>> oneOfGroups = new HashMap<>();
JBTreeTraverser.<JsonSchemaTreeNode>from(node -> node.getChildren())
.withRoot(root)
.preOrderDfsTraversal()
.consumeEach(node -> {
if (node.getChildren().isEmpty() && !node.isAny() && !node.isNothing() &&
SchemaResolveState.normal.equals(node.getResolveState())) {
int groupNumber = node.getExcludingGroupNumber();
if (groupNumber < 0) {
schemas.add(node.getSchema());
}
else {
Set<JsonSchemaObject> set = oneOfGroups.get(groupNumber);
if (set == null) oneOfGroups.put(groupNumber, (set = new HashSet<>()));
set.add(node.getSchema());
}
}
});
return new MatchResult(schemas, new ArrayList<>(oneOfGroups.values()));
}
}
@@ -181,7 +181,7 @@ open class FileBasedStorage(file: Path,
override fun toString() = file.systemIndependentPath
}
fun writeFile(file: Path?, requestor: Any, virtualFile: VirtualFile?, element: Element, lineSeparator: LineSeparator, prependXmlProlog: Boolean): VirtualFile {
internal fun writeFile(file: Path?, requestor: Any, virtualFile: VirtualFile?, element: Element, lineSeparator: LineSeparator, prependXmlProlog: Boolean): VirtualFile {
val result = if (file != null && (virtualFile == null || !virtualFile.isValid)) {
getOrCreateVirtualFile(requestor, file)
}
@@ -58,6 +58,7 @@ import gnu.trove.THashSet
import org.jdom.Element
import java.io.File
import java.io.IOException
import java.nio.file.FileSystems
import java.nio.file.Path
import java.nio.file.Paths
@@ -490,10 +491,19 @@ private fun writeConfigFile(elements: List<Element>, file: Path) {
}
elements.forEach { wrapper.addContent(it) }
// .idea component configuration files uses XML prolog due to historical reasons
file.outputStream().use {
it.write(XML_PROLOG)
it.write(LineSeparator.LF.separatorBytes)
wrapper.write(it)
if (file.fileSystem == FileSystems.getDefault()) {
// VFS must be used to write workspace.xml and misc.xml to ensure that project files will be not reloaded on external file change event
writeFile(file, object : StateStorage.SaveSession {
override fun save() {
}
}, null, wrapper, LineSeparator.LF, true)
}
else {
file.outputStream().use {
it.write(XML_PROLOG)
it.write(LineSeparator.LF.separatorBytes)
wrapper.write(it)
}
}
}
@@ -53,7 +53,7 @@ public interface ParserDefinition {
*/
@NotNull
default TokenSet getWhitespaceTokens() {
return TokenSet.WS;
return TokenSet.WHITE_SPACE;
}
/**
@@ -21,7 +21,7 @@ public class TokenSet {
public static final TokenSet ANY = new TokenSet(Short.MAX_VALUE, (short)0) {
@Override public boolean contains(IElementType t) { return true; }
};
public static final TokenSet WS = doCreate(TokenType.WHITE_SPACE);
public static final TokenSet WHITE_SPACE = doCreate(TokenType.WHITE_SPACE);
private final short myShift;
private final short myMax;
@@ -97,7 +97,7 @@ public class TokenSet {
public static TokenSet create(@NotNull IElementType... types) {
if (types.length == 0) return EMPTY;
if (types.length == 1 && types[0] == TokenType.WHITE_SPACE) {
return WS;
return WHITE_SPACE;
}
return doCreate(types);
}
@@ -462,7 +462,7 @@ public class PluginManagerCore {
PluginId pluginId = pluginDescriptor.getPluginId();
File pluginRoot = pluginDescriptor.getPath();
if (isRunningFromSources()) return null;
if (isUnitTestMode() && isRunningFromSources()) return null;
try {
final List<URL> urls = new ArrayList<>(classPath.length);
@@ -520,7 +520,7 @@ public class PluginManagerCore {
@NotNull
private static ClassLoader[] getParentLoaders(@NotNull Map<PluginId, ? extends IdeaPluginDescriptor> idToDescriptorMap, @NotNull PluginId[] pluginIds) {
if (isRunningFromSources()) return new ClassLoader[0];
if (isUnitTestMode() && isRunningFromSources()) return new ClassLoader[0];
LinkedHashSet<ClassLoader> loaders = new LinkedHashSet<>(pluginIds.length);
for (final PluginId id : pluginIds) {
@@ -848,9 +848,9 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi
oldDocumentText.charAt(prefix) == newDocumentText.charAt(prefix)) { prefix++; }
while (suffix < shortestLength - prefix &&
oldDocumentText.charAt(psiLength - suffix - 1) == newDocumentText.charAt(newDocumentText.length() - suffix - 1)) { suffix++; }
int length = Math.max(prefix, psiLength - suffix);
if (length == 0 && newDocumentText.length() == oldDocumentText.length()) return null;
return TextRange.create(prefix, length);
int end = Math.max(prefix, psiLength - suffix);
if (end == prefix && newDocumentText.length() == oldDocumentText.length()) return null;
return TextRange.create(prefix, end);
}
public static void doActualPsiChange(@NotNull final PsiFile file, @NotNull final DiffLog diffLog) {
@@ -94,7 +94,7 @@ public abstract class Identikit {
PsiElement result = findParent(startOffset, endOffset, anchor);
if (endOffset == startOffset) {
while (result == null && anchor.getTextRange().getStartOffset() == endOffset) {
while ((result == null || result.getTextRange().getStartOffset() != startOffset) && anchor.getTextRange().getStartOffset() == endOffset) {
anchor = PsiTreeUtil.prevLeaf(anchor, false);
if (anchor == null) break;
@@ -57,6 +57,7 @@ public class WizardContext extends UserDataHolderBase {
private ModulesProvider myModulesProvider;
private boolean myProjectFileDirectorySetExplicitly;
private AbstractWizard myWizard;
private String myDefaultModuleName = "untitled";
public void setProjectStorageFormat(StorageScheme format) {
myProjectStorageFormat = format;
@@ -86,6 +87,14 @@ public class WizardContext extends UserDataHolderBase {
myWizard = wizard;
}
public void setDefaultModuleName(String defaultModuleName) {
myDefaultModuleName = defaultModuleName;
}
public String getDefaultModuleName() {
return myDefaultModuleName;
}
public interface Listener {
void buttonsUpdateRequested();
void nextStepRequested();
@@ -25,6 +25,7 @@ import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.io.JarUtil;
@@ -34,6 +35,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.EncodingManager;
import com.intellij.util.PathUtil;
import com.intellij.util.PathsList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.execution.ParametersListUtil;
import com.intellij.util.lang.UrlClassLoader;
import gnu.trove.THashMap;
@@ -53,6 +55,8 @@ import java.util.jar.Manifest;
* @author max
*/
public class JdkUtil {
public static Key<Map<String, String>> COMMAND_LINE_CONTENT = Key.create("command.line.content");
/**
* The VM property is needed to workaround incorrect escaped URLs handling in WebSphere,
* see <a href="https://youtrack.jetbrains.com/issue/IDEA-126859#comment=27-778948">IDEA-126859</a> for additional details
@@ -250,6 +254,8 @@ public class JdkUtil {
}
}
commandLine.putUserData(COMMAND_LINE_CONTENT, ContainerUtil.stringMap(argFile.getAbsolutePath(), FileUtil.loadFile(argFile)));
appendEncoding(javaParameters, commandLine, vmParameters);
commandLine.addParameter("@" + argFile.getAbsolutePath());
@@ -325,12 +331,16 @@ public class JdkUtil {
}
File classpathFile = FileUtil.createTempFile("idea_classpath", null);
PathsList classPath = javaParameters.getClassPath();
try (PrintWriter writer = new PrintWriter(classpathFile)) {
for (String path : javaParameters.getClassPath().getPathList()) {
for (String path : classPath.getPathList()) {
writer.println(path);
}
}
Map<String, String> map = ContainerUtil.stringMap(classpathFile.getAbsolutePath(), classPath.getPathsString());
commandLine.putUserData(COMMAND_LINE_CONTENT, map);
Set<String> classpath = new LinkedHashSet<>();
classpath.add(PathUtil.getJarPathForClass(commandLineWrapper));
if (UrlClassLoader.class.getName().equals(vmParameters.getPropertyValue("java.system.class.loader"))) {
@@ -348,12 +358,14 @@ public class JdkUtil {
if (vmParamsFile != null) {
commandLine.addParameter("@vm_params");
commandLine.addParameter(vmParamsFile.getAbsolutePath());
map.put(vmParamsFile.getAbsolutePath(), FileUtil.loadFile(vmParamsFile));
OSProcessHandler.deleteFileOnTermination(commandLine, vmParamsFile);
}
if (appParamsFile != null) {
commandLine.addParameter("@app_params");
commandLine.addParameter(appParamsFile.getAbsolutePath());
map.put(appParamsFile.getAbsolutePath(), FileUtil.loadFile(appParamsFile));
OSProcessHandler.deleteFileOnTermination(commandLine, appParamsFile);
}
}
@@ -372,6 +384,7 @@ public class JdkUtil {
Manifest manifest = new Manifest();
manifest.getMainAttributes().putValue("Created-By", ApplicationNamesInfo.getInstance().getFullProductName());
String manifestText = "Manifest.MF";
if (dynamicVMOptions) {
List<String> properties = new ArrayList<>();
for (String param : vmParameters.getList()) {
@@ -383,6 +396,7 @@ public class JdkUtil {
}
}
manifest.getMainAttributes().putValue("VM-Options", ParametersListUtil.join(properties));
manifestText += "VM-Options: " + ParametersListUtil.join(properties) + "\n";
}
else {
commandLine.addParameters(vmParameters.getList());
@@ -392,12 +406,12 @@ public class JdkUtil {
if (dynamicParameters) {
manifest.getMainAttributes().putValue("Program-Parameters", ParametersListUtil.join(javaParameters.getProgramParametersList().getList()));
manifestText += "Program-Parameters: " + ParametersListUtil.join(javaParameters.getProgramParametersList().getList()) + "\n";
}
boolean notEscape = vmParameters.hasParameter(PROPERTY_DO_NOT_ESCAPE_CLASSPATH_URL);
List<String> classPathList = javaParameters.getClassPath().getPathList();
File classpathJarFile = CommandLineWrapperUtil.createClasspathJarFile(manifest, classPathList, notEscape);
PathsList path = javaParameters.getClassPath();
File classpathJarFile = CommandLineWrapperUtil.createClasspathJarFile(manifest, path.getPathList(), notEscape);
String jarFilePath = classpathJarFile.getAbsolutePath();
commandLine.addParameter("-classpath");
@@ -407,6 +421,8 @@ public class JdkUtil {
}
commandLine.addParameter(jarFilePath);
commandLine.putUserData(COMMAND_LINE_CONTENT, ContainerUtil.stringMap(jarFilePath, manifestText + "Class-Path: " + path.getPathsString()));
OSProcessHandler.deleteFileOnTermination(commandLine, classpathJarFile);
}
catch (IOException e) {
@@ -31,6 +31,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.ContainerUtil;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -43,23 +44,45 @@ public abstract class AbstractProjectNode extends ProjectViewNode<Project> {
}
protected Collection<AbstractTreeNode> modulesAndGroups(Collection<ModuleDescription> modules) {
Set<String> groups = new LinkedHashSet<>();
Set<String> topLevelGroups = new LinkedHashSet<>();
Set<ModuleDescription> nonGroupedModules = new LinkedHashSet<>(modules);
List<String> commonGroupsPath = null;
for (final ModuleDescription moduleDescription : modules) {
final List<String> path = ModuleGrouper.instanceFor(myProject).getGroupPath(moduleDescription);
if (!path.isEmpty()) {
final String topLevelGroupName = path.get(0);
groups.add(topLevelGroupName);
topLevelGroups.add(topLevelGroupName);
nonGroupedModules.remove(moduleDescription);
if (commonGroupsPath == null) {
commonGroupsPath = path;
}
else {
int commonPartLen = Math.min(commonGroupsPath.size(), path.size());
OptionalLong firstDifference = StreamEx.zip(commonGroupsPath.subList(0, commonPartLen), path.subList(0, commonPartLen), String::equals).indexOf(false);
if (firstDifference.isPresent()) {
commonGroupsPath = commonGroupsPath.subList(0, (int)firstDifference.getAsLong());
}
}
}
}
List<AbstractTreeNode> result = new ArrayList<>();
try {
for (String groupPath : groups) {
result.add(createModuleGroupNode(new ModuleGroup(Collections.singletonList(groupPath))));
if (modules.size() > 1) {
if (commonGroupsPath != null && !commonGroupsPath.isEmpty()) {
result.add(createModuleGroupNode(new ModuleGroup(commonGroupsPath)));
}
else {
for (String groupPath : topLevelGroups) {
result.add(createModuleGroupNode(new ModuleGroup(Collections.singletonList(groupPath))));
}
}
for (ModuleDescription moduleDescription : nonGroupedModules) {
ContainerUtil.addIfNotNull(result, createModuleNode(moduleDescription));
}
}
for (ModuleDescription moduleDescription : nonGroupedModules) {
ContainerUtil.addIfNotNull(result, createModuleNode(moduleDescription));
else {
ContainerUtil.addIfNotNull(result, createModuleNode(ContainerUtil.getFirstItem(modules)));
}
}
catch (ProcessCanceledException e) {
@@ -28,6 +28,7 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleGrouper;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.util.PlatformIcons;
@@ -110,14 +111,30 @@ public abstract class ModuleGroupNode extends ProjectViewNode<ModuleGroup> imple
@Override
public void update(PresentationData presentation) {
final String[] groupPath = getValue().getGroupPath();
presentation.setPresentableText(groupPath[groupPath.length-1]);
presentation.setPresentableText(getPresentableName());
presentation.setIcon(PlatformIcons.CLOSED_MODULE_GROUP_ICON);
}
@NotNull
private String getPresentableName() {
return StringUtil.join(getRelativeGroupPath(), ".");
}
private List<String> getRelativeGroupPath() {
AbstractTreeNode parent = getParent();
List<String> thisPath = getValue().getGroupPathList();
if (parent instanceof ModuleGroupNode) {
List<String> parentPath = ((ModuleGroupNode)parent).getValue().getGroupPathList();
if (ContainerUtil.startsWith(thisPath, parentPath)) {
return thisPath.subList(parentPath.size(), thisPath.size());
}
}
return thisPath;
}
@Override
public String getTestPresentation() {
return "Group: " + getValue();
return "Group: " + getPresentableName();
}
@Override
@@ -296,7 +296,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
@NotNull
private static JBTreeTraverser<Object> traverser() {
return new JBTreeTraverser<>(o -> (o instanceof Group ? JBIterable.from(((Group)o).getChildren()) : JBIterable.empty()));
return JBTreeTraverser.from(o -> o instanceof Group ? ((Group)o).getChildren() : null);
}
private JBIterable<Object> getSelectedElements() {
@@ -41,7 +41,6 @@ import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
import com.intellij.util.containers.JBTreeTraverser;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -289,7 +288,7 @@ public class BlockViewerPsiBasedTree implements ViewerPsiBasedTree {
private void initMap(BlockTreeNode rootBlockNode, PsiElement psiEl) {
myPsiToBlockMap = new HashMap<>();
JBTreeTraverser<BlockTreeNode> traverser = new JBTreeTraverser<>(o -> JBIterable.of(o.getChildren()));
JBTreeTraverser<BlockTreeNode> traverser = JBTreeTraverser.of(BlockTreeNode::getChildren);
for (BlockTreeNode block : traverser.withRoot(rootBlockNode)) {
PsiElement currentElem = null;
if (block.getBlock() instanceof ASTBlock) {
@@ -202,8 +202,8 @@ public abstract class DialogWrapper {
private final Alarm myErrorTextAlarm = new Alarm();
private static final Color BALLOON_BORDER = new JBColor(new Color(0xe0a8a9), new Color(0x73454b));
private static final Color BALLOON_BACKGROUND = new JBColor(new Color(0xf5e6e7), new Color(0x593d41));
private static final Color BALLOON_ERROR_BORDER = new JBColor(new Color(0xe0a8a9), new Color(0x73454b));
private static final Color BALLOON_ERROR_BACKGROUND = new JBColor(new Color(0xf5e6e7), new Color(0x593d41));
/**
* Creates modal {@code DialogWrapper}. The currently active window will be the dialog's parent.
@@ -2002,8 +2002,8 @@ public abstract class DialogWrapper {
.setHideOnKeyOutside(false)
.setHideOnClickOutside(false)
.setHideOnAction(false)
.setBorderColor(BALLOON_BORDER)
.setFillColor(BALLOON_BACKGROUND)
.setBorderColor(BALLOON_ERROR_BORDER)
.setFillColor(BALLOON_ERROR_BACKGROUND)
.setHideOnFrameResize(false)
.setRequestFocus(false)
.setAnimationCycle(100)
@@ -601,12 +601,16 @@ public abstract class MasterDetailsComponent implements Configurable, DetailsCom
return null;
}
public final MyNode getSelectedNode() {
TreePath path = myTree.getSelectionPath();
return path != null ? (MyNode)path.getLastPathComponent() : null;
}
@Nullable
public NamedConfigurable getSelectedConfigurable() {
final TreePath selectionPath = myTree.getSelectionPath();
if (selectionPath != null) {
MyNode node = (MyNode)selectionPath.getLastPathComponent();
final NamedConfigurable configurable = node.getConfigurable();
MyNode selectedNode = getSelectedNode();
if (selectedNode != null) {
final NamedConfigurable configurable = selectedNode.getConfigurable();
LOG.assertTrue(configurable != null, "already disposed");
return configurable;
}
@@ -57,7 +57,7 @@ public final class TreeUtil {
TreeModel model = tree.getModel();
Object root = model.getRoot();
TreePath rootPath = root == null ? null : new TreePath(root);
return new JBTreeTraverser<TreePath>(path -> nodeChildren(path.getLastPathComponent(), model)
return JBTreeTraverser.<TreePath>from(path -> nodeChildren(path.getLastPathComponent(), model)
.map(o -> path.pathByAddingChild(o)))
.withRoot(rootPath);
}
@@ -6,11 +6,17 @@ import java.io.File
/**
* A console filter which looks for a given path in an output and creates a link for viewing a content of that file.
*/
class ArgumentFileFilter : Filter {
class ArgumentFileFilter() : Filter {
@Volatile private var filePath: String? = null
@Volatile private var fileText: String? = null
private var triggered = false
constructor(filePath: String?, fileText: String?) : this() {
this.filePath = filePath
this.fileText = fileText
}
fun setPath(path: String) {
filePath = path
fileText = File(path).readText()
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.ui.laf;
import com.intellij.icons.AllIcons;
@@ -26,7 +12,6 @@ import com.sun.java.swing.plaf.windows.WindowsTreeUI;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.metal.MetalLookAndFeel;
import java.awt.*;
@@ -44,10 +29,10 @@ public final class IdeaLaf extends MetalLookAndFeel {
Pair<String, Integer> systemFont = UIUtil.getSystemFontData();
if (systemFont != null) {
LafManagerImpl.initFontDefaults(defaults, new FontUIResource(systemFont.first, Font.PLAIN, systemFont.second));
LafManagerImpl.initFontDefaults(defaults, UIUtil.getFontWithFallback(systemFont.first, Font.PLAIN, systemFont.second));
}
else {
LafManagerImpl.initFontDefaults(defaults, new FontUIResource("Tahoma", Font.PLAIN, 11));
LafManagerImpl.initFontDefaults(defaults, UIUtil.getFontWithFallback("Tahoma", Font.PLAIN, 11));
}
}
@@ -1,18 +1,4 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.ui.laf;
import com.intellij.CommonBundle;
@@ -675,7 +661,7 @@ public final class LafManagerImpl extends LafManager implements PersistentStateC
UISettings uiSettings = UISettings.getInstance();
if (uiSettings.getOverrideLafFonts()) {
storeOriginalFontDefaults(uiDefaults);
initFontDefaults(uiDefaults, new FontUIResource(uiSettings.getFontFace(), Font.PLAIN, uiSettings.getFontSize()));
initFontDefaults(uiDefaults, UIUtil.getFontWithFallback(uiSettings.getFontFace(), Font.PLAIN, uiSettings.getFontSize()));
JBUI.setUserScaleFactor(JBUI.getFontScale(uiSettings.getFontSize()));
}
else {
@@ -64,7 +64,15 @@ public class DarculaUIUtil {
public static final Color INACTIVE_ERROR_COLOR = new JBColor(() -> UIUtil.isUnderDefaultMacTheme() ? MAC_INACTIVE_ERROR_COLOR : DEFAULT_INACTIVE_ERROR_COLOR);
@SuppressWarnings("UseJBColor")
public static final Color WARNING_COLOR = new Color(0xf6ebbc, true);
private static final Color MAC_ACTIVE_WARNING_COLOR = new Color(0x80e9ad43, true);
private static final Color DEFAULT_ACTIVE_WARNING_COLOR = new JBColor(0xe2a53a, 0xac7920);
@SuppressWarnings("UseJBColor")
private static final Color MAC_INACTIVE_WARNING_COLOR = new Color(0x80ffda99, true);
private static final Color DEFAULT_INACTIVE_WARNING_COLOR = new JBColor(0xffd385, 0x6e5324);
public static final Color ACTIVE_WARNING_COLOR = new JBColor(() -> UIUtil.isUnderDefaultMacTheme() ? MAC_ACTIVE_WARNING_COLOR : DEFAULT_ACTIVE_WARNING_COLOR);
public static final Color INACTIVE_WARNING_COLOR = new JBColor(() -> UIUtil.isUnderDefaultMacTheme() ? MAC_INACTIVE_WARNING_COLOR : DEFAULT_INACTIVE_WARNING_COLOR);
@SuppressWarnings("UseJBColor")
private static final Color MAC_REGULAR_COLOR = new Color(0x80479cfc, true);
@@ -81,8 +89,7 @@ public class DarculaUIUtil {
warning {
public void setGraphicsColor(Graphics2D g, boolean focused) {
g.setColor(WARNING_COLOR);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, focused ? 1f : 0.5f));
g.setColor(focused ? ACTIVE_WARNING_COLOR: INACTIVE_WARNING_COLOR);
}
};
@@ -23,7 +23,6 @@ import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicArrowButton;
import java.awt.*;
@@ -206,10 +205,10 @@ public class WinIntelliJSpinnerUI extends DarculaSpinnerUI {
button.setOpaque(false);
if (direction == SwingConstants.NORTH) {
installNextButtonListeners(button);
button.setBorder(new EmptyBorder(2, 1, 1, 2));
button.setBorder(JBUI.Borders.empty(2, 1, 1, 2));
} else {
installPreviousButtonListeners(button);
button.setBorder(new EmptyBorder(1, 1, 2, 2));
button.setBorder(JBUI.Borders.empty(1, 1, 2, 2));
}
return button;
}
@@ -278,7 +277,7 @@ public class WinIntelliJSpinnerUI extends DarculaSpinnerUI {
Rectangle bounds = editor.getBounds();
Insets i = spinner.getInsets();
int offset = JBUI.scale(EDITOR_OFFSET - i.left);
int offset = JBUI.scale(EDITOR_OFFSET) - i.left;
editor.setBounds(bounds.x + offset,
bounds.y,
bounds.width - offset,
@@ -467,8 +467,9 @@ public class AbstractPopup implements JBPopup {
@Override
public void show(@NotNull RelativePoint aPoint) {
if (Registry.is("ide.helptooltip.enabled")) {
HelpTooltip.onShowMasterPopup((JComponent)aPoint.getOriginalComponent(), this);
Component c = aPoint.getOriginalComponent();
if (Registry.is("ide.helptooltip.enabled") && c instanceof JComponent) {
HelpTooltip.onShowMasterPopup((JComponent)c, this);
}
Point screenPoint = aPoint.getScreenPoint();
@@ -103,7 +103,8 @@ class ComponentWithBrowseButtonGenerator : ComponentCodeGenerator<FixedSizeButto
}
override fun generate(cmp: FixedSizeButton, me: MouseEvent, cp: Point): String {
val className = cmp.parent.parent.javaClass.simpleName
var className = cmp.parent.parent.javaClass.simpleName
if (className.isEmpty()) className = cmp.parent.parent.javaClass.genericSuperclass.typeName
return "componentWithBrowseButton($className::class.java).clickButton()"
}
}
@@ -44,6 +44,7 @@ import com.intellij.ui.components.labels.LinkLabel
import org.fest.swing.exception.ActionFailedException
import org.fest.swing.exception.ComponentLookupException
import org.fest.swing.exception.WaitTimedOutError
import org.fest.swing.fixture.AbstractComponentFixture
import org.fest.swing.fixture.JListFixture
import org.fest.swing.fixture.JTableFixture
import org.fest.swing.fixture.JTextComponentFixture
@@ -96,7 +97,7 @@ open class GuiTestCase {
/**
* default timeout to find target component for fixture. Using seconds as time unit.
*/
val defaultTimeout = 120L
var defaultTimeout = 120L
val settingsTitle: String = if (isMac()) "Preferences" else "Settings"
val defaultSettingsTitle: String = if (isMac()) "Default Preferences" else "Default Settings"
@@ -639,6 +640,25 @@ open class GuiTestCase {
return ExtendedTreeFixture(guiTestRule.robot(), myTree)
}
fun exists(fixture: () -> AbstractComponentFixture<*, *, *>): Boolean {
val tmp = defaultTimeout
defaultTimeout = 0
try {
fixture.invoke()
defaultTimeout = tmp
}
catch (ex: Exception) {
when (ex) {
is ComponentLookupException,
is WaitTimedOutError -> {
defaultTimeout = tmp; return false
}
else -> throw ex
}
}
return true
}
//*********SOME EXTENSION FUNCTIONS FOR FIXTURES
fun JListFixture.doubleClickItem(itemName: String) {
@@ -1289,15 +1289,15 @@ public class FileUtil extends FileUtilRt {
@NotNull
public static JBTreeTraverser<File> fileTraverser(@Nullable File root) {
return new JBTreeTraverser<File>(FILE_CHILDREN).withRoot(root);
return FILE_TRAVERSER.withRoot(root);
}
private static final Function<File, Iterable<File>> FILE_CHILDREN = new Function<File, Iterable<File>>() {
private static final JBTreeTraverser<File> FILE_TRAVERSER = JBTreeTraverser.from(new Function<File, Iterable<File>>() {
@Override
public Iterable<File> fun(File file) {
return file != null && file.isDirectory() ? JBIterable.of(file.listFiles()) : JBIterable.<File>empty();
}
};
});
public static boolean processFilesRecursively(@NotNull File root, @NotNull Processor<File> processor) {
return fileTraverser(root).bfsTraversal().processEach(processor);
@@ -624,13 +624,13 @@ public class ReflectionUtil {
@NotNull
public static JBTreeTraverser<Class> classTraverser(@Nullable Class root) {
return new JBTreeTraverser<Class>(CLASS_STRUCTURE).unique().withRoot(root);
return CLASS_TRAVERSER.unique().withRoot(root);
}
private static final Function<Class, Iterable<Class>> CLASS_STRUCTURE = new Function<Class, Iterable<Class>>() {
private static final JBTreeTraverser<Class> CLASS_TRAVERSER = JBTreeTraverser.from(new Function<Class, Iterable<Class>>() {
@Override
public Iterable<Class> fun(Class aClass) {
return JBIterable.of(aClass.getSuperclass()).append(aClass.getInterfaces());
}
};
});
}
@@ -1,18 +1,16 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.intellij.util.ui;
import com.intellij.BundleBase;
@@ -2657,7 +2655,7 @@ public class UIUtil {
return getFontWithFallback(font.getFamily(), font.getStyle(), font.getSize());
}
public static FontUIResource getFontWithFallback(@NotNull String familyName, @JdkConstants.FontStyle int style, int size) {
public static FontUIResource getFontWithFallback(@Nullable String familyName, @JdkConstants.FontStyle int style, int size) {
Font fontWithFallback = new StyleContext().getFont(familyName, style, size);
return fontWithFallback instanceof FontUIResource ? (FontUIResource)fontWithFallback : new FontUIResource(fontWithFallback);
}
@@ -3158,12 +3156,12 @@ public class UIUtil {
@NotNull
public static JBTreeTraverser<Component> uiTraverser(@Nullable Component component) {
return new JBTreeTraverser<Component>(COMPONENT_CHILDREN).withRoot(component);
return UI_TRAVERSER.withRoot(component);
}
public static final Key<Iterable<? extends Component>> NOT_IN_HIERARCHY_COMPONENTS = Key.create("NOT_IN_HIERARCHY_COMPONENTS");
private static final Function<Component, JBIterable<Component>> COMPONENT_CHILDREN = new Function<Component, JBIterable<Component>>() {
private static final JBTreeTraverser<Component> UI_TRAVERSER = JBTreeTraverser.from(new Function<Component, JBIterable<Component>>() {
@Override
public JBIterable<Component> fun(@NotNull Component c) {
JBIterable<Component> result;
@@ -3191,7 +3189,7 @@ public class UIUtil {
}
return result;
}
};
});
private static final Function.Mono<Component> COMPONENT_PARENT = new Function.Mono<Component>() {
@Override
@@ -0,0 +1,4 @@
File name: Foo.groovy
class <spot>Foo</spot> {
}
@@ -0,0 +1,4 @@
File name: Foo.groovy
class <spot>Bar</spot> {
}
@@ -0,0 +1,5 @@
<html>
<body>
<span>Changes class name to corresponding containing file name</span>
</body>
</html>
@@ -128,6 +128,9 @@ do.you.want.to.change.type.of.parameter.in.method=Do you want to change type of
rename.file.with.class.intention.name=Rename file to class name
rename.file.with.class.intention.family.name=Rename file to corresponding class name
rename.class.to.file.name.intention.family.name=Rename class to corresponding file name
rename.class.to.0=Rename class to ''{0}''
move.class.to.new.file.intention.name=Move to separate file
move.class.to.new.file.intention.family.name=Move class to separate file
+6 -1
View File
@@ -113,7 +113,7 @@
<membersContributor implementation="org.jetbrains.plugins.groovy.builder.StreamingJsonBuilderContributor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.builder.StreamingJsonBuilderDelegateContributor"/>
<membersContributor implementation="com.intellij.structuralsearch.IdeaOpenApiNonCodeMembersContributor"/>
<!--<membersContributor implementation="com.intellij.structuralsearch.IdeaOpenApiNonCodeMembersContributor"/>-->
<closureMissingMethodContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.PluginXmlClosureMemberContributor"/>
@@ -1457,6 +1457,11 @@
<categoryKey>intention.category.conversions</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.conversions.RenameFileWithClassIntention</className>
</intentionAction>
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.conversions</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.conversions.RenameClassToFileNameIntention</className>
</intentionAction>
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.conversions</categoryKey>
@@ -1,64 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.intentions.conversions;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
/**
* @author Maxim.Medvedev
*/
class ClassNameDiffersFromFileNamePredicate implements PsiElementPredicate {
private final Consumer<GrTypeDefinition> myClassConsumer;
private final boolean mySearchForClassInMultiClassFile;
ClassNameDiffersFromFileNamePredicate(@Nullable Consumer<GrTypeDefinition> classConsumer, boolean searchForClassInMultiClassFile) {
myClassConsumer = classConsumer;
mySearchForClassInMultiClassFile = searchForClassInMultiClassFile;
}
ClassNameDiffersFromFileNamePredicate(@Nullable Consumer<GrTypeDefinition> classConsumer) {
this(classConsumer, false);
}
@Override
public boolean satisfiedBy(@NotNull PsiElement element) {
final PsiElement parent = element.getParent();
if (!(parent instanceof GrTypeDefinition)) return false;
if (((GrTypeDefinition)parent).getNameIdentifierGroovy() != element) return false;
final String name = ((GrTypeDefinition)parent).getName();
if (name == null || name.isEmpty()) return false;
if (myClassConsumer != null) myClassConsumer.consume(((GrTypeDefinition)parent));
final PsiFile file = element.getContainingFile();
if (!(file instanceof GroovyFile)) return false;
if (!file.isPhysical()) return false;
if (name.equals(FileUtil.getNameWithoutExtension(file.getName()))) return false;
if (mySearchForClassInMultiClassFile) {
return ((GroovyFile)file).getClasses().length > 1;
}
else {
return !((GroovyFile)file).isScript();
}
}
}
@@ -0,0 +1,41 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.intentions.conversions
import com.intellij.openapi.util.io.FileUtil.getNameWithoutExtension
import com.intellij.psi.PsiElement
import com.intellij.util.Consumer
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
internal class ClassNameDiffersFromFileNamePredicate @JvmOverloads constructor(
private val searchForClassInMultiClassFile: Boolean = false,
private val classConsumer: Consumer<GrTypeDefinition>? = null,
private val fileNameConsumer: Consumer<String>? = null
) : PsiElementPredicate {
internal constructor(consumer: Consumer<GrTypeDefinition>?) : this(classConsumer = consumer)
override fun satisfiedBy(element: PsiElement): Boolean {
val clazz = element.parent as? GrTypeDefinition ?: return false
if (clazz.nameIdentifierGroovy !== element) return false
val className = clazz.name ?: return false
if (className.isEmpty()) return false
val file = clazz.parent as? GroovyFile ?: return false
if (!file.isPhysical) return false
val fileName = getNameWithoutExtension(file.name)
if (fileName.isEmpty()) return false
if (className == fileName) return false
val result = if (searchForClassInMultiClassFile) file.classes.size > 1 else !file.isScript
if (!result) return false
classConsumer?.consume(clazz)
fileNameConsumer?.consume(fileName)
return true
}
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2016 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.intentions.conversions;
import com.intellij.openapi.application.ApplicationManager;
@@ -100,6 +86,6 @@ public class MoveClassToNewFileIntention extends Intention {
@NotNull
@Override
protected PsiElementPredicate getElementPredicate() {
return new ClassNameDiffersFromFileNamePredicate(null, true);
return new ClassNameDiffersFromFileNamePredicate(true);
}
}
@@ -0,0 +1,40 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.intentions.conversions
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.SmartPsiElementPointer
import com.intellij.psi.util.createSmartPointer
import com.intellij.refactoring.RefactoringFactory
import com.intellij.util.Consumer
import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle.message
import org.jetbrains.plugins.groovy.intentions.base.Intention
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
class RenameClassToFileNameIntention : Intention() {
private lateinit var myClassPointer: SmartPsiElementPointer<GrTypeDefinition>
private lateinit var myFileName: String
override fun getElementPredicate(): PsiElementPredicate = ClassNameDiffersFromFileNamePredicate(
classConsumer = Consumer {
myClassPointer = it.createSmartPointer()
},
fileNameConsumer = Consumer { fileName ->
myFileName = fileName
}
)
override fun isStopElement(element: PsiElement?): Boolean = true
override fun getText(): String = message("rename.class.to.0", myFileName)
override fun startInWriteAction(): Boolean = false
override fun processIntention(element: PsiElement, project: Project, editor: Editor?) {
val clazz = myClassPointer.element ?: return
RefactoringFactory.getInstance(project).createRename(clazz, myFileName).run()
}
}
+2 -1
View File
@@ -4758,4 +4758,5 @@ jenkins python-jenkins
pipeline django-pipeline
PIL Pillow
robot robotframework
cv2 opencv-python
cv2 opencv-python
ldap pyldap
@@ -1,18 +1,16 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.jetbrains.python.packaging;
import com.intellij.openapi.editor.Document;
@@ -61,6 +59,10 @@ public class PyRequirement {
private static final Pattern GITHUB_ARCHIVE_URL =
Pattern.compile("https?://github\\.com/[^/\\s]+/(?<" + NAME_GROUP + ">[^/\\s]+)/archive/\\S+" + COMMENT_REGEXP);
@NotNull
private static final Pattern GITLAB_ARCHIVE_URL =
Pattern.compile("https?://gitlab\\.com/[^/\\s]+/(?<" + NAME_GROUP + ">[^/\\s]+)/repository/\\S+" + COMMENT_REGEXP);
@NotNull
private static final Pattern ARCHIVE_URL =
Pattern.compile("https?://\\S+/" +
@@ -309,11 +311,16 @@ public class PyRequirement {
@Nullable
public static PyRequirement fromLine(@NotNull String line) {
final PyRequirement githubArchiveUrl = parseGithubArchiveUrl(line);
final PyRequirement githubArchiveUrl = parseGitArchiveUrl(GITHUB_ARCHIVE_URL, line);
if (githubArchiveUrl != null) {
return githubArchiveUrl;
}
final PyRequirement gitlabArchiveUrl = parseGitArchiveUrl(GITLAB_ARCHIVE_URL, line);
if (gitlabArchiveUrl != null) {
return gitlabArchiveUrl;
}
final PyRequirement archiveUrl = parseArchiveUrl(line);
if (archiveUrl != null) {
return archiveUrl;
@@ -349,8 +356,8 @@ public class PyRequirement {
}
@Nullable
private static PyRequirement parseGithubArchiveUrl(@NotNull String line) {
final Matcher matcher = GITHUB_ARCHIVE_URL.matcher(line);
private static PyRequirement parseGitArchiveUrl(@NotNull Pattern pattern, @NotNull String line) {
final Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
return new PyRequirement(matcher.group(NAME_GROUP), Collections.emptyList(), Collections.singletonList(dropComments(line, matcher)));
@@ -13,4 +13,5 @@ django-simple-captcha
Pillow
pyzmq
robotframework
opencv-python
opencv-python
pyldap
@@ -1,4 +1,4 @@
<warning descr="Package requirements 'factory-boy', 'python-magic', 'attrs', 'python-jenkins', 'python-dateutil', 'PyYAML', 'beautifulsoup4', 'scikit-learn', 'future', 'django-pipeline', 'django_jsonfield', 'django-simple-captcha', 'Pillow', 'pyzmq', 'robotframework', 'opencv-python' are not satisfied">import factory
<warning descr="Package requirements 'factory-boy', 'python-magic', 'attrs', 'python-jenkins', 'python-dateutil', 'PyYAML', 'beautifulsoup4', 'scikit-learn', 'future', 'django-pipeline', 'django_jsonfield', 'django-simple-captcha', 'Pillow', 'pyzmq', 'robotframework', 'opencv-python', 'pyldap' are not satisfied">import factory
import magic
import attr
import jenkins
@@ -13,4 +13,5 @@ import captcha
import PIL
import zmq
import robot
import cv2</warning>
import cv2
import ldap</warning>
@@ -1,18 +1,4 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python.inspections;
import com.intellij.openapi.projectRoots.Sdk;
@@ -71,6 +57,7 @@ public class PyPackageRequirementsInspectionTest extends PyInspectionTestCase {
}
// PY-11963
// PY-26050
public void testMismatchBetweenPackageAndRequirement() {
doMultiFileTest("test1.py");
}
@@ -1,18 +1,4 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python.packaging;
import com.intellij.openapi.util.Pair;
@@ -80,6 +66,11 @@ public class PyRequirementTest extends PyTestCase {
doTest("https://github.com/divio/MyProject1/archive/master.zip?1450634746.0107164");
}
// PY-26364
public void testGitlabArchiveUrl() {
doTest("https://gitlab.com/mrh1997/MyProject1/repository/master/archive.zip");
}
// VCS
// PY-6328
public void testGit() {