mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+1
-1
@@ -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) -> 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) -> 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";
|
||||
}
|
||||
|
||||
|
||||
+60
-48
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-16
@@ -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) {
|
||||
|
||||
+12
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -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;
|
||||
|
||||
+6
-3
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-3
@@ -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); }
|
||||
}
|
||||
+63
-10
@@ -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) {
|
||||
|
||||
+29
-6
@@ -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) {
|
||||
|
||||
+20
-3
@@ -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
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
|
||||
+1
-2
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+3
-4
@@ -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();
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
File name: Foo.groovy
|
||||
|
||||
class <spot>Foo</spot> {
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
File name: Foo.groovy
|
||||
|
||||
class <spot>Bar</spot> {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<span>Changes class name to corresponding containing file name</span>
|
||||
</body>
|
||||
</html>
|
||||
+3
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
-64
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -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
|
||||
}
|
||||
}
|
||||
+2
-16
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+40
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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)));
|
||||
|
||||
+2
-1
@@ -13,4 +13,5 @@ django-simple-captcha
|
||||
Pillow
|
||||
pyzmq
|
||||
robotframework
|
||||
opencv-python
|
||||
opencv-python
|
||||
pyldap
|
||||
+3
-2
@@ -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>
|
||||
+2
-15
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user