Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-09-21 19:16:06 +03:00
376 changed files with 6382 additions and 3708 deletions
+1
View File
@@ -64,6 +64,7 @@
<module fileurl="file://$PROJECT_DIR$/java/debugger/openapi/debugger-openapi.iml" filepath="$PROJECT_DIR$/java/debugger/openapi/debugger-openapi.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/plugins/devkit/devkit.iml" filepath="$PROJECT_DIR$/plugins/devkit/devkit.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/devkit/jps-plugin/devkit-jps-plugin.iml" filepath="$PROJECT_DIR$/plugins/devkit/jps-plugin/devkit-jps-plugin.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/devkit/devkit-tests.iml" filepath="$PROJECT_DIR$/plugins/devkit/devkit-tests.iml" group="community/plugins" />
<module fileurl="file://$PROJECT_DIR$/platform/diff-api/diff-api.iml" filepath="$PROJECT_DIR$/platform/diff-api/diff-api.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/diff-impl/diff-impl.iml" filepath="$PROJECT_DIR$/platform/diff-impl/diff-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/platform/diff-impl/diff-tests.iml" filepath="$PROJECT_DIR$/platform/diff-impl/diff-tests.iml" group="platform" />
@@ -90,15 +90,18 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase {
@Override
protected void tearDown() throws Exception {
for (Artifact artifact : getArtifactManager().getArtifacts()) {
final String outputPath = artifact.getOutputPath();
if (!StringUtil.isEmpty(outputPath)) {
FileUtil.delete(new File(FileUtil.toSystemDependentName(outputPath)));
try {
for (Artifact artifact : getArtifactManager().getArtifacts()) {
final String outputPath = artifact.getOutputPath();
if (!StringUtil.isEmpty(outputPath)) {
FileUtil.delete(new File(FileUtil.toSystemDependentName(outputPath)));
}
}
CompilerTestUtil.disableExternalCompiler(getProject());
}
finally {
super.tearDown();
}
CompilerTestUtil.disableExternalCompiler(getProject());
super.tearDown();
}
protected ArtifactManager getArtifactManager() {
@@ -0,0 +1,252 @@
/*
* Copyright 2000-2015 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.debugger.actions;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.JavaStackFrame;
import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
import com.intellij.xdebugger.impl.ui.XDebuggerExpressionEditor;
import com.sun.jdi.Method;
import com.sun.jdi.Value;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class ForceEarlyReturnAction extends DebuggerAction {
public void actionPerformed(@NotNull AnActionEvent e) {
final Project project = e.getProject();
final JavaStackFrame stackFrame = PopFrameAction.getStackFrame(e);
if (stackFrame == null || project == null) {
return;
}
final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext());
final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess();
if (debugProcess == null) {
return;
}
final StackFrameProxyImpl proxy = stackFrame.getStackFrameProxy();
final ThreadReferenceProxyImpl thread = proxy.threadProxy();
debugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext, thread) {
@Override
public void threadAction() {
Method method;
try {
method = proxy.location().method();
}
catch (EvaluateException e) {
showError(project, DebuggerBundle.message("error.early.return", e.getLocalizedMessage()));
return;
}
if ("void".equals(method.returnTypeName())) {
forceEarlyReturnWithFinally(thread.getVirtualMachine().mirrorOfVoid(), stackFrame, debugProcess, null);
}
else {
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ReturnExpressionDialog(project, debugProcess.getXdebugProcess().getEditorsProvider(), debugProcess, stackFrame).show();
}
});
}
}
});
}
private static void forceEarlyReturnWithFinally(final Value value,
final JavaStackFrame frame,
final DebugProcessImpl debugProcess,
@Nullable final DialogWrapper dialog) {
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (PopFrameAction.evaluateFinallyBlocks(debugProcess.getProject(),
UIUtil.removeMnemonic(ActionsBundle.actionText("Debugger.ForceEarlyReturn")),
frame,
new XDebuggerEvaluator.XEvaluationCallback() {
@Override
public void evaluated(@NotNull XValue result) {
forceEarlyReturn(value, frame.getDescriptor().getFrameProxy().threadProxy(), debugProcess, dialog);
}
@Override
public void errorOccurred(@NotNull String errorMessage) {
showError(debugProcess.getProject(),
DebuggerBundle.message("error.executing.finally", errorMessage));
}
})) {
return;
}
forceEarlyReturn(value, frame.getDescriptor().getFrameProxy().threadProxy(), debugProcess, dialog);
}
});
}
private static void forceEarlyReturn(final Value value,
final ThreadReferenceProxyImpl thread,
final DebugProcessImpl debugProcess,
@Nullable final DialogWrapper dialog) {
debugProcess.getManagerThread().schedule(new DebuggerCommandImpl() {
@Override
protected void action() throws Exception {
try {
thread.forceEarlyReturn(value);
}
catch (Exception e) {
showError(debugProcess.getProject(), DebuggerBundle.message("error.early.return", e.getLocalizedMessage()));
return;
}
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (dialog != null) {
dialog.close(DialogWrapper.OK_EXIT_CODE);
}
debugProcess.getSession().stepInto(true, null);
}
});
}
});
}
private static void evaluateAndReturn(final Project project,
final JavaStackFrame stackFrame,
final DebugProcessImpl debugProcess,
XExpression expression,
final DialogWrapper dialog) {
XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
if (evaluator != null) {
evaluator.evaluate(expression,
new XDebuggerEvaluator.XEvaluationCallback() {
@Override
public void evaluated(@NotNull XValue result) {
if (result instanceof JavaValue) {
forceEarlyReturnWithFinally(((JavaValue)result).getDescriptor().getValue(),
stackFrame,
debugProcess,
dialog);
}
}
@Override
public void errorOccurred(@NotNull final String errorMessage) {
showError(project, DebuggerBundle.message("error.unable.to.evaluate.expression") + ": " + errorMessage);
}
}, stackFrame.getSourcePosition());
}
else {
showError(project, XDebuggerBundle.message("xdebugger.evaluate.stack.frame.has.not.evaluator"));
}
}
private static void showError(final Project project, final String message) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
Messages.showMessageDialog(project,
message,
UIUtil.removeMnemonic(ActionsBundle.actionText("Debugger.ForceEarlyReturn")),
Messages.getErrorIcon());
}
}, ModalityState.any());
}
public void update(@NotNull AnActionEvent e) {
boolean enable = false;
JavaStackFrame stackFrame = PopFrameAction.getStackFrame(e);
if (stackFrame != null && stackFrame.getDescriptor().getUiIndex() == 0) {
enable = stackFrame.getStackFrameProxy().getVirtualMachine().canForceEarlyReturn();
}
if (ActionPlaces.isMainMenuOrActionSearch(e.getPlace()) || ActionPlaces.DEBUGGER_TOOLBAR.equals(e.getPlace())) {
e.getPresentation().setEnabled(enable);
}
else {
e.getPresentation().setVisible(enable);
}
}
private static class ReturnExpressionDialog extends DialogWrapper {
private final Project myProject;
private final XDebuggerEditorsProvider myEditorsProvider;
private final DebugProcessImpl myProcess;
private final JavaStackFrame myFrame;
private final XDebuggerExpressionEditor myEditor;
public ReturnExpressionDialog(@NotNull Project project,
XDebuggerEditorsProvider provider,
DebugProcessImpl process,
JavaStackFrame frame) {
super(project);
myProject = project;
myEditorsProvider = provider;
myProcess = process;
myFrame = frame;
myEditor = new XDebuggerExpressionEditor(myProject, myEditorsProvider, "forceReturnValue", myFrame.getSourcePosition(),
XExpressionImpl.EMPTY_EXPRESSION, false);
setTitle("Return Value");
init();
}
@Nullable
@Override
protected JComponent createCenterPanel() {
return myEditor.getComponent();
}
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
return myEditor.getPreferredFocusedComponent();
}
@Override
protected void doOKAction() {
evaluateAndReturn(myProject, myFrame, myProcess, myEditor.getExpression(), this);
}
}
}
@@ -70,7 +70,7 @@ public class PopFrameAction extends DebuggerAction {
public void actionPerformed(@NotNull AnActionEvent e) {
final Project project = e.getData(CommonDataKeys.PROJECT);
final JavaStackFrame stackFrame = getStackFrame(e);
if(stackFrame == null) {
if (stackFrame == null || stackFrame.getStackFrameProxy().isBottom()) {
return;
}
try {
@@ -81,76 +81,29 @@ public class PopFrameAction extends DebuggerAction {
}
debugProcess.getSession().setSteppingThrough(stackFrame.getStackFrameProxy().threadProxy());
if (!DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) {
List<PsiStatement> statements = getFinallyStatements(debuggerContext.getSourcePosition());
if (!statements.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (PsiStatement statement : statements) {
sb.append("\n").append(statement.getText());
}
if (DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) {
evaluateAndPop(project, stackFrame, debuggerContext, debugProcess, sb);
return;
}
else {
int res = MessageDialogBuilder
.yesNoCancel(UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)),
DebuggerBundle.message("warning.finally.block.detected") + sb)
.project(project)
.icon(Messages.getWarningIcon())
.yesText(DebuggerBundle.message("button.execute.finally"))
.noText(DebuggerBundle.message("button.drop.anyway"))
.cancelText(CommonBundle.message("button.cancel"))
.doNotAsk(
new DialogWrapper.DoNotAskOption() {
@Override
public boolean isToBeShown() {
return !DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME) &&
!DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME);
}
if (evaluateFinallyBlocks(project,
UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)),
stackFrame,
new XDebuggerEvaluator.XEvaluationCallback() {
@Override
public void evaluated(@NotNull XValue result) {
popFrame(debugProcess, debuggerContext, stackFrame);
}
@Override
public void setToBeShown(boolean value, int exitCode) {
if (!value) {
DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME =
exitCode == Messages.YES ? DebuggerSettings.EVALUATE_FINALLY_ALWAYS : DebuggerSettings.EVALUATE_FINALLY_NEVER;
}
else {
DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME = DebuggerSettings.EVALUATE_FINALLY_ASK;
}
}
@Override
public boolean canBeHidden() {
return true;
}
@Override
public boolean shouldSaveOptionsOnCancel() {
return false;
}
@NotNull
@Override
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.show");
}
})
.show();
switch (res) {
case Messages.CANCEL:
return;
case Messages.NO:
break;
case Messages.YES: // evaluate finally
evaluateAndPop(project, stackFrame, debuggerContext, debugProcess, sb);
return;
}
}
}
}
debugProcess.getManagerThread().schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame.getStackFrameProxy()));
@Override
public void errorOccurred(@NotNull final String errorMessage) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
Messages
.showMessageDialog(project, DebuggerBundle.message("error.executing.finally", errorMessage),
UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)),
Messages.getErrorIcon());
}
});
}
})) return;
popFrame(debugProcess, debuggerContext, stackFrame);
}
catch (NativeMethodException e2){
Messages.showMessageDialog(project, DebuggerBundle.message("error.native.method.exception"),
@@ -162,33 +115,96 @@ public class PopFrameAction extends DebuggerAction {
}
}
private static void evaluateAndPop(final Project project,
final JavaStackFrame stackFrame,
final DebuggerContextImpl debuggerContext,
final DebugProcessImpl debugProcess, StringBuilder sb) {
static boolean evaluateFinallyBlocks(Project project,
String title,
JavaStackFrame stackFrame,
XDebuggerEvaluator.XEvaluationCallback callback) {
if (!DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) {
List<PsiStatement> statements = getFinallyStatements(stackFrame.getDescriptor().getSourcePosition());
if (!statements.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (PsiStatement statement : statements) {
sb.append("\n").append(statement.getText());
}
if (DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) {
evaluateAndAct(project, stackFrame, sb, callback);
return true;
}
else {
int res = MessageDialogBuilder
.yesNoCancel(title,
DebuggerBundle.message("warning.finally.block.detected") + sb)
.project(project)
.icon(Messages.getWarningIcon())
.yesText(DebuggerBundle.message("button.execute.finally"))
.noText(DebuggerBundle.message("button.drop.anyway"))
.cancelText(CommonBundle.message("button.cancel"))
.doNotAsk(
new DialogWrapper.DoNotAskOption() {
@Override
public boolean isToBeShown() {
return !DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME) &&
!DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME);
}
@Override
public void setToBeShown(boolean value, int exitCode) {
if (!value) {
DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME =
exitCode == Messages.YES ? DebuggerSettings.EVALUATE_FINALLY_ALWAYS : DebuggerSettings.EVALUATE_FINALLY_NEVER;
}
else {
DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME = DebuggerSettings.EVALUATE_FINALLY_ASK;
}
}
@Override
public boolean canBeHidden() {
return true;
}
@Override
public boolean shouldSaveOptionsOnCancel() {
return false;
}
@NotNull
@Override
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.show");
}
})
.show();
switch (res) {
case Messages.CANCEL:
return true;
case Messages.NO:
break;
case Messages.YES: // evaluate finally
evaluateAndAct(project, stackFrame, sb, callback);
return true;
}
}
}
}
return false;
}
private static void popFrame(DebugProcessImpl debugProcess, DebuggerContextImpl debuggerContext, JavaStackFrame stackFrame) {
debugProcess.getManagerThread()
.schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame.getStackFrameProxy()));
}
private static void evaluateAndAct(Project project,
JavaStackFrame stackFrame,
StringBuilder sb,
XDebuggerEvaluator.XEvaluationCallback callback) {
XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
if (evaluator != null) {
evaluator.evaluate(XExpressionImpl.fromText(sb.toString(), EvaluationMode.CODE_FRAGMENT),
new XDebuggerEvaluator.XEvaluationCallback() {
@Override
public void evaluated(@NotNull XValue result) {
debugProcess.getManagerThread()
.schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame.getStackFrameProxy()));
}
@Override
public void errorOccurred(@NotNull final String errorMessage) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
Messages
.showMessageDialog(project, DebuggerBundle.message("error.executing.finally", errorMessage),
UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)),
Messages.getErrorIcon());
}
});
}
}, stackFrame.getSourcePosition());
callback,
stackFrame.getSourcePosition());
}
else {
Messages.showMessageDialog(project, XDebuggerBundle.message("xdebugger.evaluate.stack.frame.has.not.evaluator"),
@@ -214,21 +230,12 @@ public class PopFrameAction extends DebuggerAction {
return res;
}
private static JavaStackFrame getStackFrame(AnActionEvent e) {
static JavaStackFrame getStackFrame(AnActionEvent e) {
StackFrameDescriptorImpl descriptor = getSelectedStackFrameDescriptor(e);
if (descriptor != null) {
if (descriptor.getFrameProxy().isBottom()) {
return null;
}
return new JavaStackFrame(descriptor, false);
}
JavaStackFrame frame = getSelectedStackFrame(e);
if (frame != null) {
StackFrameProxyImpl proxy = frame.getStackFrameProxy();
if (proxy == null || proxy.isBottom()) return null;
return frame;
}
return null;
return getSelectedStackFrame(e);
}
static StackFrameProxyImpl getStackFrameProxy(AnActionEvent e) {
@@ -397,6 +397,7 @@ public class JavaStackFrame extends XStackFrame {
}
}
@NotNull
public StackFrameProxyImpl getStackFrameProxy() {
return myDescriptor.getFrameProxy();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -30,7 +30,7 @@ public class BlockStatementEvaluator implements Evaluator {
@Override
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
Object result = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf();
Object result = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOfVoid();
for (Evaluator statement : myStatements) {
result = statement.evaluate(context);
}
@@ -37,7 +37,7 @@ public class DoWhileStatementEvaluator extends LoopEvaluator {
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf();
Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOfVoid();
while (true) {
if (body(context)) break;
@@ -29,7 +29,7 @@ public abstract class ForStatementEvaluatorBase extends LoopEvaluator {
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf();
Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOfVoid();
value = evaluateInitialization(context, value);
while (true) {
@@ -54,7 +54,7 @@ public class IfStatementEvaluator implements Evaluator {
value = myElseEvaluator.evaluate(context);
myModifier = myElseEvaluator.getModifier();
} else {
value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf();
value = context.getDebugProcess().getVirtualMachineProxy().mirrorOfVoid();
myModifier = null;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package com.intellij.debugger.jdi;
import org.jetbrains.annotations.NotNull;
/**
* Created by IntelliJ IDEA.
* User: lex
@@ -23,10 +25,10 @@ package com.intellij.debugger.jdi;
* To change this template use Options | File Templates.
*/
public abstract class JdiProxy {
protected JdiTimer myTimer;
@NotNull protected JdiTimer myTimer;
private int myTimeStamp = 0;
public JdiProxy(JdiTimer timer) {
public JdiProxy(@NotNull JdiTimer timer) {
myTimer = timer;
myTimeStamp = myTimer.getCurrentTime();
}
@@ -25,6 +25,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.jdi.StackFrameProxy;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.ThreeState;
import com.sun.jdi.*;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
@@ -46,10 +47,10 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
private StackFrame myStackFrame;
private ObjectReference myThisReference;
private ClassLoaderReference myClassLoader;
private Boolean myIsObsolete = null;
private ThreeState myIsObsolete = ThreeState.UNSURE;
private Map<LocalVariable, Value> myAllValues;
public StackFrameProxyImpl(ThreadReferenceProxyImpl threadProxy, @NotNull StackFrame frame, int fromBottomIndex /* 1-based */) {
public StackFrameProxyImpl(@NotNull ThreadReferenceProxyImpl threadProxy, @NotNull StackFrame frame, int fromBottomIndex /* 1-based */) {
super(threadProxy.getVirtualMachine());
myThreadProxy = threadProxy;
myFrameFromBottomIndex = fromBottomIndex;
@@ -59,14 +60,14 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
public boolean isObsolete() throws EvaluateException {
DebuggerManagerThreadImpl.assertIsManagerThread();
checkValid();
if (myIsObsolete != null) {
return myIsObsolete.booleanValue();
if (myIsObsolete != ThreeState.UNSURE) {
return myIsObsolete.toBoolean();
}
InvalidStackFrameException error = null;
for (int attempt = 0; attempt < 2; attempt++) {
try {
boolean isObsolete = (getVirtualMachine().canRedefineClasses() && location().method().isObsolete());
myIsObsolete = isObsolete? Boolean.TRUE : Boolean.FALSE;
myIsObsolete = ThreeState.fromBoolean(isObsolete);
return isObsolete;
}
catch (InvalidStackFrameException e) {
@@ -75,7 +76,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
}
catch (InternalException e) {
if (e.errorCode() == 23 /*INVALID_METHODID according to JDI sources*/) {
myIsObsolete = Boolean.TRUE;
myIsObsolete = ThreeState.YES;
return true;
}
throw e;
@@ -108,7 +109,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
}
myFrameIndex = -1;
myStackFrame = null;
myIsObsolete = null;
myIsObsolete = ThreeState.UNSURE;
myThisReference = null;
myClassLoader = null;
myAllValues = null;
@@ -171,6 +172,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
// return false;
// }
@NotNull
@Override
public VirtualMachineProxyImpl getVirtualMachine() {
return (VirtualMachineProxyImpl) myTimer;
@@ -65,6 +65,7 @@ public final class ThreadReferenceProxyImpl extends ObjectReferenceProxyImpl imp
return (ThreadReference)getObjectReference();
}
@NotNull
@Override
public VirtualMachineProxyImpl getVirtualMachine() {
DebuggerManagerThreadImpl.assertIsManagerThread();
@@ -309,6 +310,17 @@ public final class ThreadReferenceProxyImpl extends ObjectReferenceProxyImpl imp
}
}
public void forceEarlyReturn(Value value) throws ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException {
DebuggerManagerThreadImpl.assertIsManagerThread();
try {
getThreadReference().forceEarlyReturn(value);
}
finally {
clearCaches();
getVirtualMachineProxy().clearCaches();
}
}
public boolean isSuspended() throws ObjectCollectedException {
try {
DebuggerManagerThreadImpl.assertIsManagerThread();
@@ -88,6 +88,7 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy {
}
}
@NotNull
public VirtualMachine getVirtualMachine() {
return myVirtualMachine;
}
@@ -278,7 +279,15 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy {
return myVirtualMachine.eventRequestManager();
}
/**
* @deprecated use {@link #mirrorOfVoid()} instead
*/
@Deprecated
public VoidValue mirrorOf() throws EvaluateException {
return mirrorOfVoid();
}
public VoidValue mirrorOfVoid() {
return myVirtualMachine.mirrorOfVoid();
}
@@ -461,6 +470,15 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy {
return myPopFrames.isAvailable();
}
private final Capability myForceEarlyReturn = new Capability() {
protected boolean calcValue() {
return myVirtualMachine.canForceEarlyReturn();
}
};
public boolean canForceEarlyReturn() {
return myForceEarlyReturn.isAvailable();
}
private final Capability myCanGetInstanceInfo = new Capability() {
protected boolean calcValue() {
if (!myVersionHigher_15) {
@@ -43,13 +43,6 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
/*
execution-impl -> lang-impl(scratches are here)
compiler-impl -> lang-impl
java-impl ->execution-impl, compiler-impl
*/
public class JavaScratchRunConfigurationExtension extends RunConfigurationExtension{
private static final Key<Integer> SCRATCH_FILE_ID = Key.create("_scratch_file_id_");
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -23,14 +23,13 @@ import com.intellij.openapi.util.MultiValuesMap;
import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.vfs.*;
import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.descriptors.*;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* @author nik
@@ -77,11 +76,7 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement
@Override
@Nullable
public ConfigFile getConfigFile(ConfigFileMetaData metaData) {
final Collection<ConfigFile> descriptors = myConfigFiles.get(metaData);
if (descriptors == null || descriptors.isEmpty()) {
return null;
}
return descriptors.iterator().next();
return ContainerUtil.getFirstItem(myConfigFiles.get(metaData));
}
@Override
@@ -132,9 +127,9 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement
return myMetaDataProvider;
}
public void updateDescriptors(final MultiValuesMap<ConfigFileMetaData, ConfigFileInfo> descriptorsMap) {
Set<ConfigFile> toDelete = new HashSet<ConfigFile>(myConfigFiles.values());
Set<ConfigFile> added = new HashSet<ConfigFile>();
public void updateDescriptors(@NotNull MultiValuesMap<ConfigFileMetaData, ConfigFileInfo> descriptorsMap) {
Set<ConfigFile> toDelete = myConfigFiles.isEmpty() ? Collections.<ConfigFile>emptySet() : new HashSet<ConfigFile>(myConfigFiles.values());
Set<ConfigFile> added = null;
for (Map.Entry<ConfigFileMetaData, Collection<ConfigFileInfo>> entry : descriptorsMap.entrySet()) {
ConfigFileMetaData metaData = entry.getKey();
@@ -142,8 +137,7 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement
final Collection<ConfigFile> oldDescriptors = myConfigFiles.get(metaData);
if (oldDescriptors != null) {
for (ConfigFile descriptor : oldDescriptors) {
if (newDescriptors.contains(descriptor.getInfo())) {
newDescriptors.remove(descriptor.getInfo());
if (newDescriptors.remove(descriptor.getInfo())) {
toDelete.remove(descriptor);
}
}
@@ -152,6 +146,9 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement
final ConfigFileImpl configFile = new ConfigFileImpl(this, configuration);
Disposer.register(this, configFile);
myConfigFiles.put(metaData, configFile);
if (added == null) {
added = new THashSet<ConfigFile>();
}
added.add(configFile);
}
}
@@ -162,9 +159,11 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement
}
myCachedConfigFiles = null;
for (ConfigFile configFile : added) {
incModificationCount();
myDispatcher.getMulticaster().configFileAdded(configFile);
if (added != null) {
for (ConfigFile configFile : added) {
incModificationCount();
myDispatcher.getMulticaster().configFileAdded(configFile);
}
}
for (ConfigFile configFile : toDelete) {
incModificationCount();
@@ -19,11 +19,11 @@ import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInspection.dataFlow.instructions.*;
import com.intellij.codeInspection.dataFlow.value.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.*;
import com.intellij.util.IncorrectOperationException;
@@ -42,18 +42,20 @@ import static com.intellij.psi.CommonClassNames.*;
public class ControlFlowAnalyzer extends JavaElementVisitor {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer");
public static final String ORG_JETBRAINS_ANNOTATIONS_CONTRACT = Contract.class.getName();
private final PsiElement myCodeFragment;
private boolean myIgnoreAssertions;
private final Project myProject;
private static class CannotAnalyzeException extends RuntimeException { }
private final DfaValueFactory myFactory;
private ControlFlow myCurrentFlow;
private Stack<CatchDescriptor> myCatchStack;
private DfaValue myRuntimeException;
private DfaValue myError;
private DfaValue myString;
private PsiType myNpe;
private PsiType myAssertionError;
private final DfaValue myRuntimeException;
private final DfaValue myError;
private final DfaValue myString;
private final PsiType myNpe;
private final PsiType myAssertionError;
private final Stack<PsiElement> myElementStack = new Stack<PsiElement>();
/**
@@ -61,50 +63,45 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
*/
private FactoryMap<PsiTryStatement, DfaVariableValue> myExceptionHolders;
ControlFlowAnalyzer(final DfaValueFactory valueFactory) {
ControlFlowAnalyzer(final DfaValueFactory valueFactory, @NotNull PsiElement codeFragment, boolean ignoreAssertions) {
myFactory = valueFactory;
}
@Nullable
public ControlFlow buildControlFlow(@NotNull PsiElement codeFragment, boolean ignoreAssertions) {
if (PsiTreeUtil.findChildOfType(codeFragment, OuterLanguageElement.class) != null) {
return null;
}
myCodeFragment = codeFragment;
myProject = codeFragment.getProject();
myIgnoreAssertions = ignoreAssertions;
final PsiManager manager = codeFragment.getManager();
GlobalSearchScope scope = codeFragment.getResolveScope();
myRuntimeException = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_RUNTIME_EXCEPTION), Nullness.NOT_NULL);
myError = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_ERROR), Nullness.NOT_NULL);
myNpe = createClassType(manager, scope, JAVA_LANG_NULL_POINTER_EXCEPTION);
myAssertionError = createClassType(manager, scope, JAVA_LANG_ASSERTION_ERROR);
myString = myFactory.createTypeValue(createClassType(manager, scope, JAVA_LANG_STRING), Nullness.NOT_NULL);
myRuntimeException = myFactory.createTypeValue(createClassType(scope, JAVA_LANG_RUNTIME_EXCEPTION), Nullness.NOT_NULL);
myError = myFactory.createTypeValue(createClassType(scope, JAVA_LANG_ERROR), Nullness.NOT_NULL);
myNpe = createClassType(scope, JAVA_LANG_NULL_POINTER_EXCEPTION);
myAssertionError = createClassType(scope, JAVA_LANG_ASSERTION_ERROR);
myString = myFactory.createTypeValue(createClassType(scope, JAVA_LANG_STRING), Nullness.NOT_NULL);
myExceptionHolders = new FactoryMap<PsiTryStatement, DfaVariableValue>() {
@Nullable
@Override
protected DfaVariableValue create(PsiTryStatement key) {
String text = "java.lang.Object $exception" + myExceptionHolders.size() + "$";
PsiParameter mockVar = JavaPsiFacade.getElementFactory(manager.getProject()).createParameterFromText(text, null);
PsiParameter mockVar = JavaPsiFacade.getElementFactory(myProject).createParameterFromText(text, null);
return myFactory.getVarFactory().createVariableValue(mockVar, false);
}
};
}
@Nullable
public ControlFlow buildControlFlow() {
myCatchStack = new Stack<CatchDescriptor>();
myCurrentFlow = new ControlFlow(myFactory);
try {
codeFragment.accept(this);
myCodeFragment.accept(this);
}
catch (CannotAnalyzeException e) {
return null;
}
PsiElement parent = codeFragment.getParent();
if (parent instanceof PsiLambdaExpression && codeFragment instanceof PsiExpression) {
generateBoxingUnboxingInstructionFor((PsiExpression)codeFragment,
PsiElement parent = myCodeFragment.getParent();
if (parent instanceof PsiLambdaExpression && myCodeFragment instanceof PsiExpression) {
generateBoxingUnboxingInstructionFor((PsiExpression)myCodeFragment,
LambdaUtil.getFunctionalInterfaceReturnType((PsiLambdaExpression)parent));
addInstruction(new CheckReturnValueInstruction(codeFragment));
addInstruction(new CheckReturnValueInstruction(myCodeFragment));
}
addInstruction(new ReturnInstruction(false, null));
@@ -117,10 +114,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
private static PsiClassType createClassType(PsiManager manager, GlobalSearchScope scope, String fqn) {
PsiClass aClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(fqn, scope);
if (aClass != null) return JavaPsiFacade.getElementFactory(manager.getProject()).createType(aClass);
return JavaPsiFacade.getElementFactory(manager.getProject()).createTypeByFQClassName(fqn, scope);
private PsiClassType createClassType(GlobalSearchScope scope, String fqn) {
PsiClass aClass = JavaPsiFacade.getInstance(myProject).findClass(fqn, scope);
if (aClass != null) return JavaPsiFacade.getElementFactory(myProject).createType(aClass);
return JavaPsiFacade.getElementFactory(myProject).createTypeByFQClassName(fqn, scope);
}
private <T extends Instruction> T addInstruction(T i) {
@@ -204,7 +201,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
lExpr.accept(this);
addInstruction(new DupInstruction());
rExpr.accept(this);
addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject()));
addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, myProject));
}
else {
generateDefaultAssignmentBinOp(lExpr, rExpr, type);
@@ -234,7 +231,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
generateBoxingUnboxingInstructionFor(lExpr,exprType);
rExpr.accept(this);
generateBoxingUnboxingInstructionFor(rExpr, exprType);
addInstruction(new BinopInstruction(null, null, lExpr.getProject()));
addInstruction(new BinopInstruction(null, null, myProject));
}
@Override public void visitAssertStatement(PsiAssertStatement statement) {
@@ -672,7 +669,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
addInstruction(new PushInstruction(myFactory.createValue(caseExpression), caseExpression));
caseValue.accept(this);
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, caseExpression.getProject()));
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject));
}
else {
pushUnknown();
@@ -750,7 +747,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
addConditionalRuntimeThrow();
addInstruction(new DupInstruction());
addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, statement.getProject()));
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject));
ConditionalGotoInstruction gotoInstruction = new ConditionalGotoInstruction(null, true, null);
addInstruction(gotoInstruction);
@@ -972,7 +969,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
//if $exception$==null => continue normal execution
addInstruction(new PushInstruction(getExceptionHolder(finallyDescriptor), null));
addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, statement.getProject()));
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject));
addInstruction(new ConditionalGotoInstruction(getEndOffset(statement), false, null));
// else throw $exception$
@@ -999,7 +996,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
for (PsiType catchType : flattened) {
addInstruction(new PushInstruction(exceptionHolder, null));
addInstruction(new PushInstruction(myFactory.createTypeValue(catchType, Nullness.UNKNOWN), null));
addInstruction(new BinopInstruction(JavaTokenType.INSTANCEOF_KEYWORD, null, section.getProject()));
addInstruction(new BinopInstruction(JavaTokenType.INSTANCEOF_KEYWORD, null, myProject));
addInstruction(new ConditionalGotoInstruction(ControlFlow.deltaOffset(getStartOffset(catchBlock), -5), false, null));
}
@@ -1179,7 +1176,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
PsiType rType = rExpr.getType();
acceptBinaryRightOperand(op, type, lExpr, lType, rExpr, rType);
addInstruction(new BinopInstruction(op, expression.isPhysical() ? expression : null, expression.getProject()));
addInstruction(new BinopInstruction(op, expression.isPhysical() ? expression : null, myProject));
lExpr = rExpr;
lType = rType;
@@ -1256,7 +1253,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
operand.accept(this);
generateBoxingUnboxingInstructionFor(operand, exprType);
PsiElement psiAnchor = i == operands.length - 1 && expression.isPhysical() ? expression : null;
addInstruction(new BinopInstruction(JavaTokenType.NE, psiAnchor, expression.getProject()));
addInstruction(new BinopInstruction(JavaTokenType.NE, psiAnchor, myProject));
}
}
@@ -1399,7 +1396,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
type = ((PsiClassType)type).rawType();
}
addInstruction(new PushInstruction(myFactory.createTypeValue(type, Nullness.UNKNOWN), null));
addInstruction(new InstanceofInstruction(expression, expression.getProject(), operand, type));
addInstruction(new InstanceofInstruction(expression, myProject, operand, type));
}
else {
pushUnknown();
@@ -1481,7 +1478,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
// if a contract resulted in 'fail', handle it
addInstruction(new DupInstruction());
addInstruction(new PushInstruction(myFactory.getConstFactory().getContractFail(), null));
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, expression.getProject()));
addInstruction(new BinopInstruction(JavaTokenType.EQEQ, null, myProject));
ConditionalGotoInstruction ifNotFail = new ConditionalGotoInstruction(null, true, null);
addInstruction(ifNotFail);
returnCheckingFinally(true, expression);
@@ -34,6 +34,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.*;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Processor;
@@ -87,21 +88,23 @@ public class DataFlowRunner {
}
}
return Arrays.asList(createMemoryState());
return Collections.singletonList(createMemoryState());
}
public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock, InstructionVisitor visitor) {
Collection<DfaMemoryState> initialStates = createInitialStates(psiBlock, visitor);
return initialStates == null ? RunnerResult.NOT_APPLICABLE : analyzeMethod(psiBlock, visitor, false, initialStates);
}
@NotNull
public final RunnerResult analyzeMethod(@NotNull PsiElement psiBlock,
InstructionVisitor visitor,
boolean ignoreAssertions,
@NotNull Collection<DfaMemoryState> initialStates) {
if (PsiTreeUtil.findChildOfType(psiBlock, OuterLanguageElement.class) != null) return RunnerResult.NOT_APPLICABLE;
try {
ControlFlowAnalyzer analyzer = createControlFlowAnalyzer();
final ControlFlow flow = analyzer.buildControlFlow(psiBlock, ignoreAssertions);
final ControlFlow flow = new ControlFlowAnalyzer(myValueFactory, psiBlock, ignoreAssertions).buildControlFlow();
if (flow == null) return RunnerResult.NOT_APPLICABLE;
int[] loopNumber = LoopAnalyzer.calcInLoop(flow);
@@ -309,10 +312,6 @@ public class DataFlowRunner {
}
}
protected ControlFlowAnalyzer createControlFlowAnalyzer() {
return new ControlFlowAnalyzer(myValueFactory);
}
protected DfaMemoryState createMemoryState() {
return new DfaMemoryStateImpl(myValueFactory);
}
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
@@ -84,11 +85,14 @@ public class FindSuperElementsHelper {
ClassInheritorsSearch.search(containingClass, containingClass.getUseScope(), true, true, false).forEach(new Processor<PsiClass>() {
@Override
public boolean process(PsiClass inheritor) {
ProgressManager.checkCanceled();
for (PsiClassType interfaceType : inheritor.getImplementsListTypes()) {
ProgressManager.checkCanceled();
PsiClassType.ClassResolveResult resolved = interfaceType.resolveGenerics();
PsiClass anInterface = resolved.getElement();
if (anInterface == null || !checkedInterfaces.add(PsiAnchor.create(anInterface))) continue;
for (PsiMethod superMethod : anInterface.findMethodsByName(method.getName(), true)) {
ProgressManager.checkCanceled();
PsiClass superInterface = superMethod.getContainingClass();
if (superInterface == null) {
continue;
@@ -19,16 +19,17 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Segment;
import com.intellij.psi.ImplicitVariable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiIdentifier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ImplicitVariableElementInfoFactory implements SmartPointerElementInfoFactory {
public class ImplicitVariableElementInfoFactory extends SmartPointerElementInfoFactory {
@Override
@Nullable
public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element) {
if (element instanceof ImplicitVariable && element.isValid()) {
return new ImplicitVariableInfo((ImplicitVariable) element, element.getProject());
public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element, @NotNull PsiFile containingFile) {
if (element instanceof ImplicitVariable) {
return new ImplicitVariableInfo((ImplicitVariable) element, containingFile.getProject());
}
return null;
}
@@ -16,17 +16,18 @@
package com.intellij.psi.impl.smartPointers;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiImportList;
import com.intellij.psi.PsiJavaFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ImportListElementInfoFactory implements SmartPointerElementInfoFactory {
public class ImportListElementInfoFactory extends SmartPointerElementInfoFactory {
@Override
@Nullable
public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element) {
public SmartPointerElementInfo createElementInfo(@NotNull final PsiElement element, @NotNull PsiFile containingFile) {
if (element instanceof PsiImportList) {
return new ImportListInfo((PsiJavaFile)element.getContainingFile());
return new ImportListInfo((PsiJavaFile)containingFile);
}
return null;
}
@@ -0,0 +1,49 @@
/*
* Copyright 2000-2015 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.psi.impl.file.impl;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.ResolveScopeProvider;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Limited resolve scope for all java files in module content, but not under source roots.
* For example, java files from test data.
* There is still a possibility to modify this scope choice with the ResolveScopeEnlarger.
*/
public class JavaOutOfSourcesResolveScopeProvider extends ResolveScopeProvider {
@Nullable
@Override
public GlobalSearchScope getResolveScope(@NotNull VirtualFile file, Project project) {
// For java only! For other languages resolve may be implemented with different rules, requiring larger scope.
final FileType type = file.getFileType();
if (type instanceof LanguageFileType && ((LanguageFileType)type).getLanguage() == JavaLanguage.INSTANCE) {
ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
if (index.isInContent(file) && !index.isInSource(file)) {
return GlobalSearchScope.fileScope(project, file);
}
}
return null;
}
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.application.ReadActionProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
@@ -81,7 +82,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, Cla
AllClassesSearch.search(searchScope, project, parameters.getNameCondition()).forEach(new Processor<PsiClass>() {
@Override
public boolean process(final PsiClass aClass) {
ProgressIndicatorProvider.checkCanceled();
ProgressManager.checkCanceled();
return isJavaLangObject(aClass) || consumer.process(aClass);
}
});
@@ -95,7 +96,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, Cla
final Processor<PsiClass> processor = new ReadActionProcessor<PsiClass>() {
@Override
public boolean processInReadAction(PsiClass candidate) {
ProgressIndicatorProvider.checkCanceled();
ProgressManager.checkCanceled();
if (parameters.isCheckInheritance() || parameters.isCheckDeep() && !(candidate instanceof PsiAnonymousClass)) {
if (!candidate.isInheritor(currentBase.get(), false)) {
@@ -130,7 +131,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase<PsiClass, Cla
final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project);
while (!stack.isEmpty()) {
ProgressIndicatorProvider.checkCanceled();
ProgressManager.checkCanceled();
final PsiAnchor anchor = stack.pop();
if (!processed.add(anchor)) continue;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -16,7 +16,7 @@
package com.intellij.psi.impl.search;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Computable;
@@ -74,6 +74,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
return AllClassesSearch.search(useScope, project).forEach(new Processor<PsiClass>() {
@Override
public boolean process(final PsiClass psiClass) {
ProgressManager.checkCanceled();
if (psiClass.isInterface()) {
return consumer.process(psiClass);
}
@@ -113,7 +114,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
Map<String, List<PsiClass>> classes = new HashMap<String, List<PsiClass>>();
for (final PsiReferenceList referenceList : candidates) {
ProgressIndicatorProvider.checkCanceled();
ProgressManager.checkCanceled();
final PsiClass candidate = (PsiClass)ApplicationManager.getApplication().runReadAction(new Computable<PsiElement>() {
@Override
public PsiElement compute() {
@@ -139,6 +140,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
if (!classes.isEmpty()) {
final VirtualFile jarFile = getJarFile(aClass);
for (List<PsiClass> sameNamedClasses : classes.values()) {
ProgressManager.checkCanceled();
if (!processSameNamedClasses(consumer, sameNamedClasses, jarFile)) return false;
}
}
@@ -155,7 +157,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
});
for (PsiAnonymousClass candidate : anonymousCandidates) {
ProgressIndicatorProvider.checkCanceled();
ProgressManager.checkCanceled();
if (!checkInheritance(p, aClass, candidate, project)) continue;
if (!consumer.process(candidate)) return false;
@@ -176,6 +178,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
}
});
for (final PsiField field : fields) {
ProgressManager.checkCanceled();
if (field instanceof PsiEnumConstant) {
PsiEnumConstantInitializer initializingClass =
ApplicationManager.getApplication().runReadAction(new Computable<PsiEnumConstantInitializer>() {
@@ -210,6 +213,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
if (jarFile != null && sameNamedClasses.size() > 1) {
for (PsiClass sameNamedClass : sameNamedClasses) {
ProgressManager.checkCanceled();
boolean fromSameJar = Comparing.equal(getJarFile(sameNamedClass), jarFile);
if (fromSameJar) {
sameJarClassFound = true;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -119,7 +119,7 @@ public class MethodUsagesSearcher extends QueryExecutorBase<PsiReference, Method
});
}
static <T> T resolveInReadAction(@NotNull Project p, Computable<T> computable) {
static <T> T resolveInReadAction(@NotNull Project p, @NotNull Computable<T> computable) {
return ApplicationManager.getApplication().isReadAccessAllowed() ? computable.compute() : DumbService.getInstance(p).runReadActionInSmartMode(computable);
}
@@ -151,7 +151,7 @@ public class PsiPrimitiveType extends PsiType.Stub {
//[ven]previous call returns null for NULL, VOID
if (boxedQName == null) return null;
JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject());
PsiClass aClass = facade.findClass(boxedQName, context.getResolveScope());
PsiClass aClass = facade.findClass(boxedQName, file.getResolveScope());
if (aClass == null) return null;
PsiElementFactory factory = facade.getElementFactory();
@@ -117,6 +117,10 @@ public class JavaConstantExpressionEvaluator extends JavaRecursiveElementWalking
final PsiConstantEvaluationHelper.AuxEvaluator auxEvaluator) {
if (expression == null) return null;
if (expression instanceof PsiLiteralExpression) {
return ((PsiLiteralExpression)expression).getValue(); // don't bother with caching etc
}
JavaConstantExpressionEvaluator evaluator = new JavaConstantExpressionEvaluator(visitedVars, throwExceptionOnOverflow, expression.getProject(), auxEvaluator);
if (expression instanceof PsiCompiledElement) {
@@ -16,14 +16,9 @@
package com.intellij.psi.impl.source;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.LightVirtualFile;
import org.jetbrains.annotations.NotNull;
public class PsiJavaFileImpl extends PsiJavaFileBaseImpl {
@@ -31,19 +26,6 @@ public class PsiJavaFileImpl extends PsiJavaFileBaseImpl {
super(JavaStubElementTypes.JAVA_FILE, JavaStubElementTypes.JAVA_FILE, file);
}
@NotNull
@Override
public GlobalSearchScope getResolveScope() {
final VirtualFile file = getVirtualFile();
if (file != null && !(file instanceof LightVirtualFile)) {
final FileIndexFacade index = ServiceManager.getService(getProject(), FileIndexFacade.class);
if (!index.isInSource(file) && !index.isInLibraryClasses(file)) {
return GlobalSearchScope.fileScope(this);
}
}
return super.getResolveScope();
}
@Override
@NotNull
public FileType getFileType() {
@@ -26,6 +26,7 @@ import com.intellij.psi.scope.JavaScopeProcessorEvent;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.util.containers.MostlySingularMultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author max
@@ -33,6 +34,7 @@ import org.jetbrains.annotations.NotNull;
public class SymbolCollectingProcessor extends BaseScopeProcessor implements ElementClassHint {
private final MostlySingularMultiMap<String, ResultWithContext> myResult = new MostlySingularMultiMap<String, ResultWithContext>();
private PsiElement myCurrentFileContext = null;
private PsiAnchor myCurrentContextAnchor = null;
@Override
public <T> T getHint(@NotNull Key<T> hintKey) {
@@ -47,6 +49,7 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele
public void handleEvent(@NotNull PsiScopeProcessor.Event event, Object associated) {
if (event == JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT) {
myCurrentFileContext = (PsiElement)associated;
myCurrentContextAnchor = null;
}
}
@@ -56,7 +59,11 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele
PsiNamedElement named = (PsiNamedElement)element;
String name = named.getName();
if (name != null) {
myResult.add(name, new ResultWithContext(named, myCurrentFileContext));
PsiAnchor context = myCurrentContextAnchor;
if (context == null && myCurrentFileContext != null) {
myCurrentContextAnchor = context = PsiAnchor.create(myCurrentFileContext);
}
myResult.add(name, new ResultWithContext(named, context));
}
}
return true;
@@ -75,9 +82,9 @@ public class SymbolCollectingProcessor extends BaseScopeProcessor implements Ele
private final PsiAnchor myElement;
private final PsiAnchor myFileContext;
public ResultWithContext(@NotNull PsiNamedElement element, PsiElement fileContext) {
public ResultWithContext(@NotNull PsiNamedElement element, @Nullable PsiAnchor fileContext) {
myElement = PsiAnchor.create(element);
myFileContext = fileContext == null ? null : PsiAnchor.create(fileContext);
myFileContext = fileContext;
}
@NotNull
@@ -42,12 +42,8 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement
private PsiElement myCurrentFileContext = null;
public VariableResolverProcessor(@NotNull PsiJavaCodeReferenceElement place, @NotNull PsiFile placeFile) {
super(place.getText(), ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new SmartList<CandidateInfo>(), place, placeFile);
super(place.getReferenceName(), ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new SmartList<CandidateInfo>(), place, placeFile);
PsiElement referenceName = place.getReferenceNameElement();
if (referenceName instanceof PsiIdentifier){
setName(referenceName.getText());
}
PsiClass access = null;
PsiElement qualifier = place.getQualifier();
if (qualifier instanceof PsiExpression) {
@@ -108,6 +104,7 @@ public class VariableResolverProcessor extends ConflictFilterProcessor implement
@Override
public <T> T getHint(@NotNull Key<T> hintKey) {
if (hintKey == ElementClassHint.KEY) {
//noinspection unchecked
return (T)this;
}
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>testSimple_0.iml</file>
<file>testSimple.iml</file>
<problem_class>Unused library</problem_class>
<description>Unused library 'JUnit'</description>
</problem>
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2015 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.execution;
import com.intellij.execution.application.ApplicationConfigurable;
@@ -135,7 +150,7 @@ public class ConfigurationsTest extends BaseConfigurationTestCase {
PsiClass testA = findTestA(getModule1());
JUnitConfiguration configuration = createConfiguration(testA);
JavaParameters parameters = checkCanRun(configuration);
CHECK.empty(parameters.getVMParametersList().getList());
assertEmpty(parameters.getVMParametersList().getList());
final SegmentedOutputStream notifications = new SegmentedOutputStream(System.out);
assertTrue(JUnitStarter.checkVersion(parameters.getProgramParametersList().getArray(),
new PrintStream(notifications)));
@@ -29,7 +29,7 @@ public class JavaFormatterMultilineMethodCallParamsTest extends AbstractJavaForm
);
}
public void IGNORED_testChainedMethodInsideCall_WithRParenOnNewLine() {
public void testChainedMethodInsideCall_WithRParenOnNewLine() {
doMethodTest(
"call(new StringBuilder()\n" +
".append(\"aaa\")\n" +
@@ -41,6 +41,31 @@ public class JavaFormatterMultilineMethodCallParamsTest extends AbstractJavaForm
");"
);
}
public void testLambdas() {
doTextTest(
"public class Main {\n" +
" public static void main(String... args) throws Exception {\n" +
" RatpackServer.start(server -> server\n" +
" .handlers(chain -> chain\n" +
" .get(ctx -> ctx.render(\"Hello World!\"))\n" +
" .get(\":name\", ctx -> ctx.render(\"Hello \" + ctx.getPathTokens().get(\"name\") + \"!\"))\n" +
" )\n" +
" );\n" +
" }\n" +
"}",
"public class Main {\n" +
" public static void main(String... args) throws Exception {\n" +
" RatpackServer.start(server -> server\n" +
" .handlers(chain -> chain\n" +
" .get(ctx -> ctx.render(\"Hello World!\"))\n" +
" .get(\":name\", ctx -> ctx.render(\"Hello \" + ctx.getPathTokens().get(\"name\") + \"!\"))\n" +
" )\n" +
" );\n" +
" }\n" +
"}"
);
}
public void testChainedMethodInsideCall_Shifted() {
doMethodTest(
@@ -16,36 +16,23 @@
package com.intellij.refactoring;
import com.intellij.JavaTestUtil;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor;
import com.intellij.refactoring.move.moveClassesOrPackages.SingleSourceRootMoveDestination;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.refactoring.util.RefactoringConflictsUtil;
import com.intellij.testFramework.*;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.*;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Consumer;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
import java.io.File;
import java.util.Collections;
public class MultipleJdksMoveClassTest extends RefactoringTestCase {
public class MultipleJdksMoveClassTest extends UsefulTestCase {
private CodeInsightTestFixture myFixture;
private Module myJava7Module;
private Module myJava8Module;
@@ -127,9 +127,7 @@ public class RootsChangedTest extends ModuleTestCase {
public void testEditLibraryForModuleLoadFromXml() throws IOException {
final File tempDirectory = createTempDirectory();
ApplicationManager.getApplication().runWriteAction(() -> {
File moduleFile =
PathManagerEx.findFileUnderProjectHome("java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml", RootsChangedTest.this.getClass());
Module a = loadModule(moduleFile, true);
Module a = loadModule(PathManagerEx.getHomePath(getClass()) + "/java/java-tests/testData/moduleRootManager/rootsChanged/emptyModule/a.iml");
assertEventsCount(1);
final Sdk jdk = IdeaTestUtil.getMockJdk17();
@@ -16,8 +16,8 @@
package com.intellij.compiler;
import com.intellij.compiler.server.BuildManager;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
@@ -31,9 +31,11 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.testFramework.EdtTestUtil;
import com.intellij.util.SmartList;
import com.intellij.util.ThrowableRunnable;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
@@ -55,22 +57,22 @@ public class CompilerTestUtil {
}
public static void saveApplicationSettings() {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
EdtTestUtil.runInEdtAndWait(new Runnable() {
@Override
public void run() {
doSaveComponent(ProjectJdkTable.getInstance());
doSaveComponent(FileTypeManager.getInstance());
}
}, ModalityState.any());
});
}
public static void saveApplicationComponent(final Object appComponent) {
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
EdtTestUtil.runInEdtAndWait(new Runnable() {
@Override
public void run() {
doSaveComponent(appComponent);
}
}, ModalityState.any());
});
}
private static void doSaveComponent(Object appComponent) {
@@ -89,27 +91,36 @@ public class CompilerTestUtil {
}.execute();
}
public static void disableExternalCompiler(final Project project) {
ApplicationManagerEx.getApplicationEx().doNotSave(true);
final JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
new WriteAction() {
@Override
protected void run(@NotNull final Result result) {
Module[] modules = ModuleManager.getInstance(project).getModules();
Sdk internalJdk = table.getInternalJdk();
List<Module> modulesToRestore = new ArrayList<Module>();
for (Module module : modules) {
Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && sdk.equals(internalJdk)) {
modulesToRestore.add(module);
public static void disableExternalCompiler(@NotNull final Project project) {
try {
EdtTestUtil.runInEdtAndWait(new ThrowableRunnable<Throwable>() {
@Override
public void run() throws Throwable {
JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
AccessToken token = WriteAction.start();
try {
Sdk internalJdk = table.getInternalJdk();
List<Module> modulesToRestore = new SmartList<Module>();
for (Module module : ModuleManager.getInstance(project).getModules()) {
Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
if (sdk != null && sdk.equals(internalJdk)) {
modulesToRestore.add(module);
}
}
table.removeJdk(internalJdk);
for (Module module : modulesToRestore) {
ModuleRootModificationUtil.setModuleSdk(module, internalJdk);
}
BuildManager.getInstance().clearState(project);
}
finally {
token.finish();
}
}
table.removeJdk(internalJdk);
for (Module module : modulesToRestore) {
ModuleRootModificationUtil.setModuleSdk(module, internalJdk);
}
BuildManager.getInstance().clearState(project);
}
}.execute();
});
}
finally {
ApplicationManagerEx.getApplicationEx().doNotSave(true);
}
}
}
@@ -39,10 +39,11 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.CompositeException;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.SmartList;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.lang.CompoundRuntimeException;
import com.intellij.util.ui.UIUtil;
import com.sun.jdi.Method;
import com.sun.jdi.ThreadReference;
@@ -58,7 +59,7 @@ public abstract class ExecutionWithDebuggerToolsTestCase extends ExecutionTestCa
private final SynchronizationBasedSemaphore myScriptRunnablesSema = new SynchronizationBasedSemaphore();
protected static final int RATHER_LATER_INVOKES_N = 10;
public DebugProcessImpl myDebugProcess = null;
private final CompositeException myException = new CompositeException();
private final List<Throwable> myException = new SmartList<Throwable>();
private static class InvokeRatherLaterRequest {
private final DebuggerCommandImpl myDebuggerCommand;
@@ -112,13 +113,17 @@ public abstract class ExecutionWithDebuggerToolsTestCase extends ExecutionTestCa
@Override
protected void tearDown() throws Exception {
super.tearDown();
throwExceptionsIfAny();
try {
super.tearDown();
}
finally {
throwExceptionsIfAny();
}
}
protected void throwExceptionsIfAny() throws CompositeException {
protected void throwExceptionsIfAny() {
synchronized (myException) {
myException.throwIfNotEmpty();
CompoundRuntimeException.throwIfNotEmpty(myException);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -31,13 +31,10 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.CompilerTester;
import com.intellij.testFramework.IdeaTestCase;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.*;
import com.intellij.util.Alarm;
import com.intellij.util.PathUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ThrowableRunnable;
import org.jetbrains.annotations.NonNls;
import java.io.File;
@@ -70,16 +67,10 @@ public abstract class ExecutionTestCase extends IdeaTestCase {
}
myModuleOutputDir = new File(ourOutputRoot, PathUtil.getFileName(getTestAppPath()));
myChecker = initOutputChecker();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
EdtTestUtil.runInEdtAndWait(new ThrowableRunnable<Throwable>() {
@Override
public void run() {
try {
ExecutionTestCase.super.setUp();
}
catch (Throwable e) {
e.printStackTrace();
assertTrue(false);
}
public void run() throws Throwable {
ExecutionTestCase.super.setUp();
}
});
if (!myModuleOutputDir.exists()) {
@@ -129,7 +120,7 @@ public abstract class ExecutionTestCase extends IdeaTestCase {
}
@Override
protected void runBareRunnable(Runnable runnable) throws Throwable {
protected void runBareRunnable(ThrowableRunnable<Throwable> runnable) throws Throwable {
runnable.run();
}
@@ -144,15 +135,10 @@ public abstract class ExecutionTestCase extends IdeaTestCase {
if (myCompilerTester != null) {
myCompilerTester.tearDown();
}
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
EdtTestUtil.runInEdtAndWait(new ThrowableRunnable<Throwable>() {
@Override
public void run() {
try {
ExecutionTestCase.super.tearDown();
}
catch (Exception e) {
LOG.error(e);
}
public void run() throws Throwable {
ExecutionTestCase.super.tearDown();
}
});
//myChecker.checkValid(getTestProjectJdk());
@@ -16,17 +16,15 @@
package com.intellij.testFramework;
import com.intellij.ide.highlighter.ModuleFileType;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.components.ComponentsPackage;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.StdModuleTypes;
import com.intellij.openapi.module.impl.ModuleImpl;
import com.intellij.openapi.project.ex.ProjectEx;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
@@ -34,6 +32,9 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.util.Consumer;
import com.intellij.util.SmartList;
import com.intellij.util.lang.CompoundRuntimeException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,7 +42,7 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public abstract class ModuleTestCase extends IdeaTestCase {
protected final Collection<Module> myModulesToDispose = new ArrayList<Module>();
@@ -55,18 +56,30 @@ public abstract class ModuleTestCase extends IdeaTestCase {
@Override
protected void tearDown() throws Exception {
try {
final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
for (Module module : myModulesToDispose) {
ModuleManager moduleManager = ModuleManager.getInstance(myProject);
List<Throwable> errors = null;
AccessToken token = WriteAction.start();
try {
for (Module module : myModulesToDispose) {
try {
String moduleName = module.getName();
if (moduleManager.findModuleByName(moduleName) != null) {
moduleManager.disposeModule(module);
}
}
catch (Throwable e) {
if (errors == null) {
errors = new SmartList<Throwable>();
}
errors.add(e);
}
}
});
}
finally {
token.finish();
}
CompoundRuntimeException.throwIfNotEmpty(errors);
}
finally {
myModulesToDispose.clear();
@@ -97,53 +110,45 @@ public abstract class ModuleTestCase extends IdeaTestCase {
return module;
}
protected Module loadModule(final File moduleFile) {
return loadModule(moduleFile, false);
}
protected Module loadModule(@NotNull String modulePath) {
String normalizedPath = FileUtil.toSystemIndependentName(modulePath);
LocalFileSystem.getInstance().refreshAndFindFileByPath(normalizedPath);
protected Module loadModule(final File moduleFile, final boolean loadComponentStates) {
Module module = ApplicationManager.getApplication().runWriteAction(
new Computable<Module>() {
@Override
public Module compute() {
ProjectImpl project = (ProjectImpl)myProject;
boolean oldOptimiseTestLoadSpeed = project.isOptimiseTestLoadSpeed();
if (loadComponentStates) {
project.setOptimiseTestLoadSpeed(false);
}
try {
LocalFileSystem.getInstance().refreshIoFiles(Collections.singletonList(moduleFile));
return ModuleManager.getInstance(myProject).loadModule(moduleFile.getAbsolutePath());
}
catch (Exception e) {
LOG.error(e);
return null;
}
finally {
project.setOptimiseTestLoadSpeed(oldOptimiseTestLoadSpeed);
}
}
}
);
ModuleManager moduleManager = ModuleManager.getInstance(myProject);
Module module;
AccessToken token = WriteAction.start();
try {
module = moduleManager.loadModule(normalizedPath);
}
catch (Exception e) {
LOG.error(e);
return null;
}
finally {
token.finish();
}
myModulesToDispose.add(module);
return module;
}
protected Module loadModule(final String modulePath) {
return loadModule(new File(modulePath));
@Nullable
protected Module loadAllModulesUnder(@NotNull VirtualFile rootDir) {
return loadAllModulesUnder(rootDir, null);
}
@Nullable
protected Module loadAllModulesUnder(@NotNull VirtualFile rootDir) throws Exception {
protected Module loadAllModulesUnder(@NotNull VirtualFile rootDir, @Nullable final Consumer<Module> moduleConsumer) {
final Ref<Module> result = Ref.create();
VfsUtilCore.visitChildrenRecursively(rootDir, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
if (!file.isDirectory() && file.getName().endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) {
ModuleImpl module = (ModuleImpl)loadModule(new File(file.getPath()));
readJdomExternalizables(module);
ModuleImpl module = (ModuleImpl)loadModule(file.getPath());
if (moduleConsumer != null) {
moduleConsumer.consume(module);
}
result.setIfNull(module);
}
return true;
@@ -153,21 +158,6 @@ public abstract class ModuleTestCase extends IdeaTestCase {
return result.get();
}
protected void readJdomExternalizables(@NotNull Module module) {
loadModuleComponentState(module, ModuleRootManager.getInstance(module));
}
protected final void loadModuleComponentState(@NotNull Module module, @NotNull Object component) {
ProjectEx project = (ProjectEx)myProject;
project.setOptimiseTestLoadSpeed(false);
try {
ComponentsPackage.getStateStore(module).initComponent(component, false);
}
finally {
project.setOptimiseTestLoadSpeed(true);
}
}
protected Module createModuleFromTestData(final String dirInTestData, final String newModuleFileName, final ModuleType moduleType,
final boolean addSourceRoot)
throws IOException {
@@ -62,11 +62,15 @@ public abstract class PsiTestCase extends ModuleTestCase {
@Override
protected void tearDown() throws Exception {
myPsiManager = null;
myFile = null;
myTestDataBefore = null;
myTestDataAfter = null;
super.tearDown();
try {
myPsiManager = null;
myFile = null;
myTestDataBefore = null;
myTestDataAfter = null;
}
finally {
super.tearDown();
}
}
@NotNull
@@ -27,6 +27,7 @@ import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -39,6 +40,7 @@ import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.ModuleFixture;
import com.intellij.testFramework.fixtures.TestFixtureBuilder;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NonNls;
import java.io.File;
@@ -116,51 +118,59 @@ abstract class JavaModuleFixtureBuilderImpl<T extends ModuleFixture> extends Mod
protected void initModule(final Module module) {
super.initModule(module);
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
final LibraryTable libraryTable = model.getModuleLibraryTable();
for (Lib lib : myLibraries) {
String libraryName = lib.getName();
final Library library = libraryTable.createLibrary(libraryName);
final Library.ModifiableModel libraryModel = library.getModifiableModel();
for (OrderRootType rootType : OrderRootType.getAllTypes()) {
final String[] roots = lib.getRoots(rootType);
for (String root : roots) {
VirtualFile vRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(root);
if (vRoot != null && OrderRootType.CLASSES.equals(rootType) && !vRoot.isDirectory()) {
final VirtualFile jar = JarFileSystem.getInstance().refreshAndFindFileByPath(root + "!/");
if (jar != null) vRoot = jar;
ModuleRootModificationUtil.updateModel(module, new Consumer<ModifiableRootModel>() {
@Override
public void consume(ModifiableRootModel model) {
LibraryTable libraryTable = model.getModuleLibraryTable();
for (Lib lib : myLibraries) {
Library library = libraryTable.createLibrary(lib.getName());
Library.ModifiableModel libraryModel = library.getModifiableModel();
boolean success = false;
try {
for (OrderRootType rootType : OrderRootType.getAllTypes()) {
for (String root : lib.getRoots(rootType)) {
VirtualFile vRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(root);
if (vRoot != null && OrderRootType.CLASSES.equals(rootType) && !vRoot.isDirectory()) {
VirtualFile jar = JarFileSystem.getInstance().refreshAndFindFileByPath(root + "!/");
if (jar != null) {
vRoot = jar;
}
}
if (vRoot != null) {
libraryModel.addRoot(vRoot, rootType);
}
}
}
success = true;
}
if (vRoot != null) {
libraryModel.addRoot(vRoot, rootType);
finally {
if (!success) {
Disposer.dispose(libraryModel);
}
}
libraryModel.commit();
}
final Sdk jdk;
if (myJdk != null) {
VfsRootAccess.allowRootAccessTemporarily(module, myJdk);
jdk = JavaSdk.getInstance().createJdk(module.getName() + "_jdk", myJdk, false);
((ProjectJdkImpl)jdk).setVersionString(StringUtil.notNullize(IdeaTestUtil.getMockJdkVersion(myJdk), "java 1.5"));
}
else {
jdk = IdeaTestUtil.getMockJdk17();
}
model.setSdk(new MockJdkWrapper(CompilerConfigurationImpl.getTestsExternalCompilerHome(), jdk));
if (myLanguageLevel != null) {
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(myLanguageLevel);
}
else if (myMockJdkLevel == MockJdkLevel.jdk15) {
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_5);
}
}
libraryModel.commit();
}
final Sdk jdk;
if (myJdk != null) {
VfsRootAccess.allowRootAccessTemporarily(module, myJdk);
jdk = JavaSdk.getInstance().createJdk(module.getName() + "_jdk", myJdk, false);
((ProjectJdkImpl)jdk).setVersionString(StringUtil.notNullize(IdeaTestUtil.getMockJdkVersion(myJdk), "java 1.5"));
}
else {
jdk = IdeaTestUtil.getMockJdk17();
}
model.setSdk(new MockJdkWrapper(CompilerConfigurationImpl.getTestsExternalCompilerHome(), jdk));
if (myLanguageLevel != null) {
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(myLanguageLevel);
}
else if (myMockJdkLevel == MockJdkLevel.jdk15) {
model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_5);
}
model.commit();
});
for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
if (entry instanceof LibraryOrderEntry) {
+1 -1
View File
@@ -13,7 +13,7 @@
<orderEntry type="library" name="JDOM" level="project" />
<orderEntry type="library" name="Log4J" level="project" />
<orderEntry type="module" module-name="lang-api" exported="" />
<orderEntry type="module" module-name="lang-impl" exported="" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="module" module-name="compiler-impl" />
<orderEntry type="module" module-name="java-impl" exported="" />
<orderEntry type="module" module-name="execution-impl" exported="" scope="RUNTIME" />
@@ -59,7 +59,7 @@ public abstract class DefaultProjectProfileManager extends ProjectProfileManager
protected final Project myProject;
private String myProjectProfile;
/** This field is used for serialization. Do not rename it or make access weaker */
@OptionTag("USE_PROJECT_PROFILE")
private boolean useProjectProfile = true;
@@ -21,7 +21,6 @@ import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.JDOMExternalizableStringList;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
@@ -47,7 +46,7 @@ import java.util.List;
* User: anna
* Date: 24-Feb-2006
*/
public class SeverityRegistrar implements JDOMExternalizable, Comparator<HighlightSeverity> {
public class SeverityRegistrar implements Comparator<HighlightSeverity> {
@NonNls private static final String INFO_TAG = "info";
@NonNls private static final String COLOR_ATTRIBUTE = "color";
private final Map<String, SeverityBasedTextAttributes> myMap = ContainerUtil.newConcurrentMap();
@@ -132,7 +131,6 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
}
@Override
public void readExternal(Element element) {
myMap.clear();
myRendererColors.clear();
@@ -178,7 +176,6 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
severitiesChanged();
}
@Override
public void writeExternal(Element element) {
List<HighlightSeverity> list = getOrderAsList(getOrderMap());
for (HighlightSeverity severity : list) {
@@ -124,6 +124,15 @@ public class FileReferenceSet {
return "/";
}
protected int findSeparatorLength(@NotNull CharSequence sequence, int atOffset) {
return StringUtil.startsWith(sequence, atOffset, getSeparatorString()) ?
getSeparatorString().length() : 0;
}
protected int findSeparatorOffset(@NotNull CharSequence sequence, int startingFrom) {
return StringUtil.indexOf(sequence, getSeparatorString(), startingFrom);
}
/**
* This should be removed. Please use {@link FileReference#getContexts()} instead.
*/
@@ -216,17 +225,12 @@ public class FileReferenceSet {
}
protected void reparse() {
String str = myPathStringNonTrimmed;
final List<FileReference> referencesList = reparse(str, myStartInElement);
List<FileReference> referencesList = reparse(myPathStringNonTrimmed, myStartInElement);
myReferences = referencesList.toArray(new FileReference[referencesList.size()]);
}
protected List<FileReference> reparse(String str, int startInElement) {
String separatorString = getSeparatorString(); // separator's length can be more then 1 char
int sepLen = separatorString.length();
int currentSlash = -sepLen;
int wsHead = 0;
int wsTail = 0;
LiteralTextEscaper<? extends PsiLanguageInjectionHost> escaper;
@@ -239,7 +243,7 @@ public class FileReferenceSet {
StringBuilder sb = new StringBuilder();
escaper.decode(valueRange, sb);
decoded = sb;
currentSlash += startInElement - valueRange.getStartOffset();
wsHead += Math.max(0, startInElement - valueRange.getStartOffset());
}
else {
escaper = null;
@@ -248,36 +252,38 @@ public class FileReferenceSet {
}
List<FileReference> referencesList = ContainerUtil.newArrayList();
// skip head white spaces
for (int i = currentSlash + sepLen; i < decoded.length() && Character.isWhitespace(decoded.charAt(i)); i++) {
currentSlash++;
for (int i = wsHead; i < decoded.length() && Character.isWhitespace(decoded.charAt(i)); i++) {
wsHead++; // skip head white spaces
}
// skip tail white spaces
for (int i = decoded.length() - 1; i >= 0 && Character.isWhitespace(decoded.charAt(i)); i--) {
wsTail++;
wsTail++; // skip tail white spaces
}
if (currentSlash + 2 * sepLen < decoded.length() &&
StringUtil.equals(decoded.subSequence(currentSlash + sepLen, currentSlash + 2 * sepLen), separatorString)) {
currentSlash += sepLen;
}
int index = 0;
int curSep = findSeparatorOffset(decoded, wsHead);
int sepLen = curSep >= wsHead ? findSeparatorLength(decoded, curSep) : 0;
if (decoded.equals(separatorString)) {
TextRange r = new TextRange(startInElement, offset(sepLen, escaper, valueRange) + 1);
referencesList.add(createFileReference(r, index++, separatorString));
if (curSep >= 0 && decoded.length() == wsHead + sepLen + wsTail) {
// add extra reference for the only & leading "/"
TextRange r = TextRange.create(startInElement, offset(curSep + Math.max(0, sepLen - 1), escaper, valueRange) + 1);
referencesList.add(createFileReference(r, 0, decoded.subSequence(curSep, curSep + sepLen).toString()));
}
while (true) {
int nextSlash = StringUtil.indexOf(decoded, separatorString, currentSlash + sepLen);
String subReferenceText = decoded.subSequence(currentSlash + sepLen, nextSlash > 0 ? nextSlash : decoded.length()).toString();
int end = nextSlash > 0 ? nextSlash : Math.max(currentSlash + sepLen, decoded.length() - 1 - wsTail);
TextRange r = new TextRange(offset(currentSlash + sepLen, escaper, valueRange),
offset(end, escaper, valueRange) + (nextSlash > 0 ? 0 : 1));
referencesList.add(createFileReference(r, index++, subReferenceText));
if ((currentSlash = nextSlash) < 0) {
break;
}
curSep = curSep == wsHead ? curSep + sepLen : wsHead; // reset offsets & start again for simplicity
sepLen = 0;
while (curSep >= 0) {
int nextSep = findSeparatorOffset(decoded, curSep + sepLen);
int start = curSep + sepLen;
int endTrimmed = nextSep > 0 ? nextSep : Math.max(start, decoded.length() - wsTail);
int endInclusive = nextSep > 0 ? nextSep : Math.max(start, decoded.length() - 1 - wsTail);
// todo move ${placeholder} support (the str usage below) to a reference implementation
// todo reference-set should be bound to exact range & text in a file, consider: ${slash}path${slash}file&amp;.txt
String refText = index == 0 && nextSep < 0 && !StringUtil.contains(decoded, str) ? str :
decoded.subSequence(start, endTrimmed).toString();
TextRange r = new TextRange(offset(start, escaper, valueRange),
offset(endInclusive, escaper, valueRange) + (nextSep < 0 && refText.length() > 0 ? 1 : 0));
referencesList.add(createFileReference(r, index++, refText));
curSep = nextSep;
sepLen = curSep > 0 ? findSeparatorLength(decoded, curSep) : 0;
}
return referencesList;
@@ -44,9 +44,9 @@ import java.io.File
import java.net.InetAddress
import java.net.UnknownHostException
public class BuiltInWebServer : HttpRequestHandler() {
class BuiltInWebServer : HttpRequestHandler() {
companion object {
val LOG = Logger.getInstance(javaClass<BuiltInWebServer>())
val LOG = Logger.getInstance(BuiltInWebServer::class.java)
private fun doProcess(request: FullHttpRequest, context: ChannelHandlerContext, projectNameAsHost: String?): Boolean {
val decodedPath = URLUtil.unescapePercentSequences(UriUtil.trimParameters(request.uri()))
@@ -67,15 +67,15 @@ public class BuiltInWebServer : HttpRequestHandler() {
}
var candidateByDirectoryName: Project? = null
val project = ProjectManager.getInstance().getOpenProjects().firstOrNull(fun(project: Project): Boolean {
if (project.isDisposed()) {
val project = ProjectManager.getInstance().openProjects.firstOrNull(fun(project: Project): Boolean {
if (project.isDisposed) {
return false
}
val name = project.getName()
val name = project.name
if (isCustomHost) {
// domain name is case-insensitive
if (projectName.equals(project.getName(), ignoreCase = true)) {
if (projectName.equals(project.name, ignoreCase = true)) {
return true
}
}
@@ -101,7 +101,7 @@ public class BuiltInWebServer : HttpRequestHandler() {
if (emptyPath) {
if (!SystemInfoRt.isFileSystemCaseSensitive) {
// may be passed path is not correct
projectName = project.getName()
projectName = project.name
}
// we must redirect "jsdebug" to "jsdebug/" as nginx does, otherwise browser will treat it as file instead of directory, so, relative path will not work
@@ -110,7 +110,7 @@ public class BuiltInWebServer : HttpRequestHandler() {
}
val path = FileUtil.toCanonicalPath(decodedPath.substring(offset + 1), '/')
for (pathHandler in WebServerPathHandler.EP_NAME.getExtensions()) {
for (pathHandler in WebServerPathHandler.EP_NAME.extensions) {
try {
if (pathHandler.process(path, project, request, context, projectName, decodedPath, isCustomHost)) {
return true
@@ -157,12 +157,12 @@ public class BuiltInWebServer : HttpRequestHandler() {
}
public fun compareNameAndProjectBasePath(projectName: String, project: Project): Boolean {
val basePath = project.getBasePath()
val basePath = project.basePath
return basePath != null && basePath.length() > projectName.length() && basePath.endsWith(projectName) && basePath.charAt(basePath.length() - projectName.length() - 1) == '/'
}
public fun findIndexFile(basedir: VirtualFile): VirtualFile? {
val children = basedir.getChildren()
val children = basedir.children
if (children == null || children.isEmpty()) {
return null
}
@@ -171,8 +171,8 @@ public fun findIndexFile(basedir: VirtualFile): VirtualFile? {
var index: VirtualFile? = null
val preferredName = indexNamePrefix + "html"
for (child in children) {
if (!child.isDirectory()) {
val name = child.getName()
if (!child.isDirectory) {
val name = child.name
//noinspection IfStatementWithIdenticalBranches
if (name == preferredName) {
return child
@@ -196,11 +196,11 @@ public fun isOwnHostName(host: String): Boolean {
try {
val address = InetAddress.getByName(host)
if (host == address.getHostAddress() || host.equals(address.getCanonicalHostName(), ignoreCase = true)) {
if (host == address.hostAddress || host.equals(address.canonicalHostName, ignoreCase = true)) {
return true
}
val localHostName = InetAddress.getLocalHost().getHostName()
val localHostName = InetAddress.getLocalHost().hostName
// WEB-8889
// develar.local is own host name: develar. equals to "develar.labs.intellij.net" (canonical host name)
return localHostName.equals(host, ignoreCase = true) || (host.endsWith(".local") && localHostName.regionMatches(0, host, 0, host.length() - ".local".length(), true))
@@ -214,8 +214,8 @@ private class StaticFileHandler : WebServerFileHandler() {
private var ssiProcessor: SsiProcessor? = null
override fun process(file: VirtualFile, canonicalRequestPath: CharSequence, project: Project, request: FullHttpRequest, channel: Channel, isCustomHost: Boolean): Boolean {
if (file.isInLocalFileSystem()) {
val nameSequence = file.getNameSequence()
if (file.isInLocalFileSystem) {
val nameSequence = file.nameSequence
//noinspection SpellCheckingInspection
if (StringUtilRt.endsWithIgnoreCase(nameSequence, ".shtml") || StringUtilRt.endsWithIgnoreCase(nameSequence, ".stm") || StringUtilRt.endsWithIgnoreCase(nameSequence, ".shtm")) {
processSsi(file, canonicalRequestPath, project, request, channel, isCustomHost)
@@ -231,17 +231,17 @@ private class StaticFileHandler : WebServerFileHandler() {
}
}
else {
val response = FileResponses.prepareSend(request, channel, file.getTimeStamp(), file.getPath()) ?: return true
val response = FileResponses.prepareSend(request, channel, file.timeStamp, file.path) ?: return true
val keepAlive = addKeepAliveIfNeed(response, request)
if (request.method() !== HttpMethod.HEAD) {
HttpUtil.setContentLength(response, file.getLength())
HttpUtil.setContentLength(response, file.length)
}
channel.write(response)
if (request.method() != HttpMethod.HEAD) {
channel.write(ChunkedStream(file.getInputStream()))
channel.write(ChunkedStream(file.inputStream))
}
val future = channel.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)
@@ -267,9 +267,9 @@ private class StaticFileHandler : WebServerFileHandler() {
val keepAlive: Boolean
var releaseBuffer = true
try {
val lastModified = ssiProcessor!!.process(SsiExternalResolver(project, request, path, file.getParent()), VfsUtilCore.loadText(file), file.getTimeStamp(), ByteBufUtf8Writer(buffer))
val lastModified = ssiProcessor!!.process(SsiExternalResolver(project, request, path, file.parent), VfsUtilCore.loadText(file), file.timeStamp, ByteBufUtf8Writer(buffer))
val response = FileResponses.prepareSend(request, channel, lastModified, file.getPath()) ?: return
val response = FileResponses.prepareSend(request, channel, lastModified, file.path) ?: return
keepAlive = addKeepAliveIfNeed(response, request)
if (request.method() !== HttpMethod.HEAD) {
@@ -296,5 +296,5 @@ private class StaticFileHandler : WebServerFileHandler() {
}
// deny access to .htaccess files
private fun hasAccess(result: File) = !result.isDirectory() && result.canRead() && !(result.isHidden() || result.getName().startsWith(".ht"))
private fun hasAccess(result: File) = !result.isDirectory && result.canRead() && !(result.isHidden || result.name.startsWith(".ht"))
}
@@ -22,7 +22,7 @@ import org.jetbrains.util.concurrency
import org.jetbrains.util.concurrency.toPromise
import javax.swing.Icon
val LOG: Logger = Logger.getInstance(javaClass<NetService>())
val LOG: Logger = Logger.getInstance(NetService::class.java)
public abstract class NetService @jvmOverloads protected constructor(protected val project: Project, private val consoleManager: ConsoleManager = ConsoleManager()) : Disposable {
protected val processHandler: AsyncValueLoader<OSProcessHandler> = object : AsyncValueLoader<OSProcessHandler>() {
@@ -76,7 +76,7 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer<String>, private
override fun channelInactive(context: ChannelHandlerContext) {
try {
if (!dataBuffers.isEmpty()) {
if (!dataBuffers.isEmpty) {
dataBuffers.forEachEntry(object : TIntObjectProcedure<ByteBuf> {
override fun execute(a: Int, buffer: ByteBuf): Boolean {
try {
@@ -92,7 +92,7 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer<String>, private
}
}
finally {
super<Decoder>.channelInactive(context)
super.channelInactive(context)
}
}
@@ -136,8 +136,10 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer<String>, private
data.writerIndex(data.writerIndex() + data.readableBytes())
}
else {
// must be computed here before we set data to new composite buffer
val newLength = data.readableBytes() + sliced.readableBytes()
data = context.alloc().compositeBuffer(Decoder.DEFAULT_MAX_COMPOSITE_BUFFER_COMPONENTS).addComponents(data, sliced)
data.writerIndex(data.writerIndex() + data.readableBytes() + sliced.readableBytes())
data.writerIndex(data.writerIndex() + newLength)
}
dataBuffers.put(id, data)
}
@@ -153,7 +155,7 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer<String>, private
}
}
else -> LOG.error("Unknown type " + type)
else -> LOG.error("Unknown type $type")
}
return null
}
@@ -12,7 +12,7 @@ import io.netty.handler.codec.http.HttpHeaderNames
import org.jetbrains.builtInWebServer.WebServerPathToFileManager
import org.jetbrains.io.Responses
import java.net.InetSocketAddress
import java.util.Locale
import java.util.*
class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) {
companion object {
@@ -37,8 +37,8 @@ class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) {
public fun writeFileHeaders(file: VirtualFile, project: Project, canonicalRequestPath: CharSequence) {
val root = WebServerPathToFileManager.getInstance(project).getRoot(file)
LOG.assertTrue(root != null)
addHeader("DOCUMENT_ROOT", root!!.getRoot().getPath())
addHeader("SCRIPT_FILENAME", file.getPath())
addHeader("DOCUMENT_ROOT", root!!.root.path)
addHeader("SCRIPT_FILENAME", file.path)
addHeader("SCRIPT_NAME", canonicalRequestPath)
}
@@ -80,19 +80,19 @@ class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) {
addHeader("REQUEST_METHOD", request.method().name())
val remote = clientChannel.remoteAddress() as InetSocketAddress
addHeader("REMOTE_ADDR", remote.getAddress().getHostAddress())
addHeader("REMOTE_PORT", Integer.toString(remote.getPort()))
addHeader("REMOTE_ADDR", remote.address.hostAddress)
addHeader("REMOTE_PORT", Integer.toString(remote.port))
val local = clientChannel.localAddress() as InetSocketAddress
addHeader("SERVER_SOFTWARE", Responses.getServerHeaderValue())
addHeader("SERVER_NAME", Responses.getServerHeaderValue())
addHeader("SERVER_ADDR", local.getAddress().getHostAddress())
addHeader("SERVER_PORT", Integer.toString(local.getPort()))
addHeader("SERVER_ADDR", local.address.hostAddress)
addHeader("SERVER_PORT", Integer.toString(local.port))
addHeader("GATEWAY_INTERFACE", "CGI/1.1")
addHeader("SERVER_PROTOCOL", request.protocolVersion().text())
addHeader("CONTENT_TYPE", request.headers().get(HttpHeaderNames.CONTENT_TYPE))
addHeader("CONTENT_TYPE", request.headers().getAsString(HttpHeaderNames.CONTENT_TYPE))
// PHP only, required if PHP was built with --enable-force-cgi-redirect
addHeader("REDIRECT_STATUS", "200")
@@ -106,8 +106,8 @@ class FastCgiRequest(val requestId: Int, allocator: ByteBufAllocator) {
addHeader("CONTENT_LENGTH", request.content().readableBytes().toString())
for (entry in request.headers()) {
addHeader("HTTP_${entry.getKey().replace('-', '_').toUpperCase(Locale.ENGLISH)}", entry.getValue())
for ((key, value) in request.headers().iteratorAsString()) {
addHeader("HTTP_${key.replace('-', '_').toUpperCase(Locale.ENGLISH)}", value)
}
}
@@ -30,7 +30,7 @@ import org.jetbrains.concurrency.Promise
import org.jetbrains.io.*
import java.util.concurrent.atomic.AtomicInteger
val LOG: Logger = Logger.getInstance(javaClass<FastCgiService>())
val LOG: Logger = Logger.getInstance(FastCgiService::class.java)
// todo send FCGI_ABORT_REQUEST if client channel disconnected
public abstract class FastCgiService(project: Project) : SingleConnectionNetService(project) {
@@ -51,7 +51,7 @@ public abstract class FastCgiService(project: Project) : SingleConnectionNetServ
private fun parseHeaders(response: HttpResponse, buffer: ByteBuf) {
val builder = StringBuilder()
while (buffer.isReadable()) {
while (buffer.isReadable) {
builder.setLength(0)
var key: String? = null
@@ -149,10 +149,10 @@ public abstract class FastCgiService(project: Project) : SingleConnectionNetServ
fastCgiRequest.writeToServerChannel(notEmptyContent, processChannel!!)
}
})
.rejected(Consumer {
.rejected {
Promise.logError(LOG, it)
handleError(fastCgiRequest, notEmptyContent)
})
}
}
}
catch (e: Throwable) {
@@ -187,7 +187,7 @@ public abstract class FastCgiService(project: Project) : SingleConnectionNetServ
fun responseReceived(id: Int, buffer: ByteBuf?) {
val channel = requests.remove(id)
if (channel == null || !channel.isActive()) {
if (channel == null || !channel.isActive) {
buffer?.release()
return
}
@@ -38,7 +38,7 @@ class TestManager(val projectRule: ProjectRule, private val tempDirManager: Temp
public val status: Int = 200)
override fun starting(description: Description) {
annotation = description.getAnnotation(javaClass<TestDescriptor>())
annotation = description.getAnnotation(TestDescriptor::class.java)
if (annotation == null) {
return
}
@@ -37,6 +37,10 @@ class ApplicationPathMacroManager : BasePathMacroManager(null)
class ApplicationStoreImpl(private val application: Application, pathMacroManager: PathMacroManager) : ComponentStoreImpl() {
override val storageManager = ApplicationStorageManager(application, pathMacroManager)
// number of app components require some state, so, we load default state in test mode
override val loadPolicy: StateLoadPolicy
get() = if (application.isUnitTestMode()) StateLoadPolicy.LOAD_ONLY_DEFAULT else StateLoadPolicy.LOAD
override fun setPath(path: String) {
storageManager.addMacro(ROOT_CONFIG, path)
storageManager.addMacro(StoragePathMacros.APP_CONFIG, "$path/${ApplicationStorageManager.FILE_STORAGE_DIR}")
@@ -31,7 +31,10 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.Project
import com.intellij.openapi.util
import com.intellij.openapi.util.*
import com.intellij.openapi.util.InvalidDataException
import com.intellij.openapi.util.JDOMExternalizable
import com.intellij.openapi.util.JDOMUtil
import com.intellij.openapi.util.NamedJDOMExternalizable
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
@@ -49,7 +52,7 @@ import java.io.IOException
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
private val LOG = Logger.getInstance(javaClass<ComponentStoreImpl>())
private val LOG = Logger.getInstance(ComponentStoreImpl::class.java)
/**
* <b>Note:</b> this class is used in upsource, please notify upsource team in case you change its API.
@@ -61,6 +64,9 @@ abstract class ComponentStoreImpl : IComponentStore {
protected open val project: Project?
get() = null
open val loadPolicy: StateLoadPolicy
get() = StateLoadPolicy.LOAD
abstract val storageManager: StateStorageManager
override final fun getStateStorageManager() = storageManager
@@ -82,6 +88,7 @@ abstract class ComponentStoreImpl : IComponentStore {
componentNameIfStateExists = if (component is PersistentStateComponent<*>) {
val stateSpec = StoreUtil.getStateSpec(component)
doAddComponent(stateSpec.name, component)
@suppress("UNCHECKED_CAST")
initPersistentComponent(stateSpec, component as PersistentStateComponent<Any>, null, false)
}
else {
@@ -129,8 +136,10 @@ abstract class ComponentStoreImpl : IComponentStore {
}
}
errors = doSave(externalizationSession!!.createSaveSessions(), readonlyFiles, errors)
CompoundRuntimeException.doThrow(errors)
if (externalizationSession != null) {
errors = doSave(externalizationSession.createSaveSessions(), readonlyFiles, errors)
}
CompoundRuntimeException.throwIfNotEmpty(errors)
}
override TestOnly fun saveApplicationComponent(component: Any) {
@@ -157,7 +166,7 @@ abstract class ComponentStoreImpl : IComponentStore {
val token = WriteAction.start()
try {
VfsRootAccess.allowRootAccess(file.getAbsolutePath())
CompoundRuntimeException.doThrow(doSave(sessions))
CompoundRuntimeException.throwIfNotEmpty(doSave(sessions))
}
finally {
try {
@@ -194,18 +203,18 @@ abstract class ComponentStoreImpl : IComponentStore {
val componentName = ComponentManagerImpl.getComponentName(component)
doAddComponent(componentName, component)
if (optimizeTestLoading()) {
if (loadPolicy != StateLoadPolicy.LOAD) {
return null
}
try {
getDefaultState(component, componentName, javaClass<Element>())?.let { component.readExternal(it) }
getDefaultState(component, componentName, Element::class.java)?.let { component.readExternal(it) }
}
catch (e: Throwable) {
LOG.error(e)
}
val element = storageManager.getOldStorage(component, componentName, StateStorageOperation.READ)?.getState(component, componentName, javaClass<Element>(), null, false) ?: return null
val element = storageManager.getOldStorage(component, componentName, StateStorageOperation.READ)?.getState(component, componentName, Element::class.java, null, false) ?: return null
try {
component.readExternal(element)
}
@@ -224,8 +233,8 @@ abstract class ComponentStoreImpl : IComponentStore {
}
}
private fun <T : Any> initPersistentComponent(stateSpec: State, component: PersistentStateComponent<T>, changedStorages: Set<StateStorage>?, reloadData: Boolean): String? {
if (optimizeTestLoading()) {
private fun <T: Any> initPersistentComponent(stateSpec: State, component: PersistentStateComponent<T>, changedStorages: Set<StateStorage>?, reloadData: Boolean): String? {
if (loadPolicy == StateLoadPolicy.NOT_LOAD) {
return null
}
@@ -236,41 +245,44 @@ abstract class ComponentStoreImpl : IComponentStore {
}
val defaultState = if (stateSpec.defaultStateAsResource) getDefaultState(component, name, stateClass) else null
val storageSpecs = getStorageSpecs(component, stateSpec, StateStorageOperation.READ)
val storageChooser = component as? StateStorageChooserEx
for (storageSpec in storageSpecs) {
if (storageChooser?.getResolution(storageSpec, StateStorageOperation.READ) == Resolution.SKIP) {
continue
}
val storage = storageManager.getStateStorage(storageSpec)
var stateGetter = if (isUseLoadedStateAsExisting(storage) && (ApplicationManager.getApplication().isUnitTestMode() || Registry.`is`("use.loaded.state.as.existing", false))) {
(storage as? StorageBaseEx<*>)?.createGetSession(component, name, stateClass)
}
else {
null
}
var state = if (stateGetter == null) storage.getState(component, name, stateClass, defaultState, reloadData) else stateGetter.getState(defaultState)
if (state == null) {
if (changedStorages != null && changedStorages.contains(storage)) {
// state will be null if file deleted
// we must create empty (initial) state to reinit component
state = DefaultStateSerializer.deserializeState(Element("state"), stateClass, null)!!
}
else {
if (loadPolicy == StateLoadPolicy.LOAD) {
val storageSpecs = getStorageSpecs(component, stateSpec, StateStorageOperation.READ)
val storageChooser = component as? StateStorageChooserEx
for (storageSpec in storageSpecs) {
if (storageChooser?.getResolution(storageSpec, StateStorageOperation.READ) == Resolution.SKIP) {
continue
}
}
try {
component.loadState(state)
val storage = storageManager.getStateStorage(storageSpec)
var stateGetter = if (isUseLoadedStateAsExisting(storage) && (ApplicationManager.getApplication().isUnitTestMode() || Registry.`is`("use.loaded.state.as.existing", false))) {
(storage as? StorageBaseEx<*>)?.createGetSession(component, name, stateClass)
}
else {
null
}
var state = if (stateGetter == null) storage.getState(component, name, stateClass, defaultState, reloadData) else stateGetter.getState(defaultState)
if (state == null) {
if (changedStorages != null && changedStorages.contains(storage)) {
// state will be null if file deleted
// we must create empty (initial) state to reinit component
state = DefaultStateSerializer.deserializeState(Element("state"), stateClass, null)!!
}
else {
continue
}
}
try {
component.loadState(state)
}
finally {
stateGetter?.close()
}
return name
}
finally {
stateGetter?.close()
}
return name
}
// we load default state even if isLoadComponentState false - required for app components (for example, at least one color scheme must exists)
if (defaultState != null) {
component.loadState(defaultState)
}
@@ -298,7 +310,14 @@ abstract class ComponentStoreImpl : IComponentStore {
if (storages.size() == 1 || component is StateStorageChooserEx) {
return storages
}
assert(!storages.isEmpty())
if (storages.isEmpty()) {
if (stateSpec.defaultStateAsResource) {
return storages
}
throw AssertionError("No storage specified")
}
val defaultStorages = selectDefaultStorages(storages, operation)
if (defaultStorages != null) {
@@ -330,8 +349,6 @@ abstract class ComponentStoreImpl : IComponentStore {
return sorted
}
protected open fun optimizeTestLoading(): Boolean = false
override final fun isReloadPossible(componentNames: MutableSet<String>) = !componentNames.any { isNotReloadable(it) }
private fun isNotReloadable(component: Any?) = component != null && (component !is PersistentStateComponent<*> || !StoreUtil.getStateSpec(component).reloadable)
@@ -357,6 +374,7 @@ abstract class ComponentStoreImpl : IComponentStore {
override final fun reloadState(componentClass: Class<out PersistentStateComponent<*>>) {
val stateSpec = StoreUtil.getStateSpecOrError(componentClass)
@suppress("UNCHECKED_CAST")
val component = components.get(stateSpec.name) as PersistentStateComponent<Any>?
if (component != null) {
initPersistentComponent(stateSpec, component, emptySet(), true)
@@ -364,6 +382,7 @@ abstract class ComponentStoreImpl : IComponentStore {
}
private fun reloadState(componentName: String, changedStorages: Set<StateStorage>): Boolean {
@suppress("UNCHECKED_CAST")
val component = components.get(componentName) as PersistentStateComponent<Any>?
if (component == null) {
return false
@@ -447,4 +466,8 @@ abstract class ComponentStoreImpl : IComponentStore {
return errors
}
}
}
enum class StateLoadPolicy {
LOAD, LOAD_ONLY_DEFAULT, NOT_LOAD
}
@@ -30,6 +30,10 @@ class DefaultProjectStoreImpl(override val project: ProjectImpl, private val pat
val FILE_SPEC = "${StoragePathMacros.APP_CONFIG}/project.default.xml"
}
// see note about default state in project store
override val loadPolicy: StateLoadPolicy
get() = if (ApplicationManager.getApplication().isUnitTestMode()) StateLoadPolicy.NOT_LOAD else StateLoadPolicy.LOAD
init {
service<DefaultProjectExportableAndSaveTrigger>().project = project
}
@@ -17,11 +17,11 @@ package com.intellij.configurationStore
import com.intellij.openapi.components.PathMacroManager
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.ex.ProjectEx
import java.io.File
class ModuleStoreImpl(module: Module, private val pathMacroManager: PathMacroManager) : ComponentStoreImpl() {
open private class ModuleStoreImpl(module: Module, private val pathMacroManager: PathMacroManager) : ComponentStoreImpl() {
override val project = module.getProject()
override val storageManager = ModuleStateStorageManager(pathMacroManager.createTrackingSubstitutor(), module)
@@ -32,7 +32,20 @@ class ModuleStoreImpl(module: Module, private val pathMacroManager: PathMacroMan
}
}
override fun optimizeTestLoading() = (project as ProjectEx).isOptimiseTestLoadSpeed()
override final fun getPathMacroManagerForDefaults() = pathMacroManager
}
private class TestModuleStore(module: Module, pathMacroManager: PathMacroManager) : ModuleStoreImpl(module, pathMacroManager) {
private var moduleComponentLoadPolicy: StateLoadPolicy? = null
override fun setPath(path: String) {
super.setPath(path)
if (File(path).exists()) {
moduleComponentLoadPolicy = StateLoadPolicy.LOAD
}
}
override val loadPolicy: StateLoadPolicy
get() = moduleComponentLoadPolicy ?: (project.stateStore as ProjectStoreImpl).loadPolicy
}
@@ -20,6 +20,6 @@ import com.intellij.openapi.project.impl.ProjectStoreClassProvider
class PlatformProjectStoreClassProvider : ProjectStoreClassProvider {
override fun getProjectStoreClass(isDefaultProject: Boolean): Class<out IComponentStore> {
return if (isDefaultProject) javaClass<DefaultProjectStoreImpl>() else javaClass<ProjectStoreImpl>()
return if (isDefaultProject) DefaultProjectStoreImpl::class.java else ProjectStoreImpl::class.java
}
}
@@ -19,6 +19,7 @@ import com.intellij.ide.highlighter.ProjectFileType
import com.intellij.ide.highlighter.WorkspaceFileType
import com.intellij.notification.Notifications
import com.intellij.notification.NotificationsManager
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.invokeAndWaitIfNeed
import com.intellij.openapi.components.*
@@ -41,7 +42,7 @@ import java.io.BufferedReader
import java.io.File
import java.io.IOException
import java.io.InputStreamReader
import java.util.ArrayList
import java.util.*
open class ProjectStoreImpl(override val project: ProjectImpl, private val pathMacroManager: PathMacroManager) : ComponentStoreImpl(), IProjectStore {
// protected setter used in upsource
@@ -50,11 +51,20 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM
private var presentableUrl: String? = null
override var loadPolicy = StateLoadPolicy.LOAD
init {
assert(!project.isDefault())
}
override fun optimizeTestLoading() = project.isOptimiseTestLoadSpeed()
override final fun isOptimiseTestLoadSpeed() = loadPolicy != StateLoadPolicy.LOAD
override final fun setOptimiseTestLoadSpeed(value: Boolean) {
// we don't load default state in tests as app store does because
// 1) we should not do it
// 2) it was so before, so, we preserve old behavior (otherwise RunManager will load template run configurations)
loadPolicy = if (value) StateLoadPolicy.NOT_LOAD else StateLoadPolicy.LOAD
}
override final fun getPathMacroManagerForDefaults() = pathMacroManager
@@ -74,6 +84,11 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM
invokeAndWaitIfNeed {
VfsUtil.markDirtyAndRefresh(false, true, false, fs.refreshAndFindFileByPath(filePath), fs.refreshAndFindFileByPath(workspacePath))
}
if (ApplicationManager.getApplication().isUnitTestMode()) {
// load state only if there are existing files
setOptimiseTestLoadSpeed(!File(filePath).exists())
}
}
else {
scheme = StorageScheme.DIRECTORY_BASED
@@ -91,6 +106,11 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM
}
invokeAndWaitIfNeed { VfsUtil.markDirtyAndRefresh(false, true, true, fs.refreshAndFindFileByPath(projectConfigDir)) }
if (ApplicationManager.getApplication().isUnitTestMode()) {
// load state only if there are existing files
setOptimiseTestLoadSpeed(!dirStore.exists())
}
}
presentableUrl = null
@@ -130,7 +150,6 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM
}
catch (ignored: IOException) {
}
}
}
@@ -184,7 +203,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM
super<ComponentStoreImpl>.doSave(saveSessions, readonlyFiles, errors)
val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(javaClass<UnableToSaveProjectNotification>(), project)
val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification::class.java, project)
if (readonlyFiles.isEmpty()) {
for (notification in notifications) {
notification.expire()
@@ -216,7 +235,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM
}
if (errors != null) {
CompoundRuntimeException.doThrow(errors)
CompoundRuntimeException.throwIfNotEmpty(errors)
}
if (!readonlyFiles.isEmpty()) {
@@ -267,7 +286,7 @@ open class ProjectStoreImpl(override val project: ProjectImpl, private val pathM
}
private fun dropUnableToSaveProjectNotification(project: Project, readOnlyFiles: Array<VirtualFile>) {
val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(javaClass<UnableToSaveProjectNotification>(), project)
val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification::class.java, project)
if (notifications.isEmpty()) {
Notifications.Bus.notify(UnableToSaveProjectNotification(project, readOnlyFiles), project)
}
@@ -28,7 +28,7 @@ import com.intellij.openapi.vfs.VirtualFile
class PlatformLangProjectStoreClassProvider : ProjectStoreClassProvider {
override fun getProjectStoreClass(isDefaultProject: Boolean): Class<out IComponentStore> {
return if (isDefaultProject) javaClass<DefaultProjectStoreImpl>() else javaClass<ProjectWithModulesStoreImpl>()
return if (isDefaultProject) DefaultProjectStoreImpl::class.java else ProjectWithModulesStoreImpl::class.java
}
}
@@ -83,7 +83,7 @@ public abstract class SchemeManagerFactoryBase : SchemesManagerFactory(), Settin
}
}
CompoundRuntimeException.doThrow(errors)
CompoundRuntimeException.throwIfNotEmpty(errors)
}
}
@@ -349,7 +349,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
val fileNameWithoutExtension = fileName.subSequence(0, fileName.length() - extension.length()).toString()
if (duringLoad) {
if (filesToDelete.isNotEmpty() && filesToDelete.contains(fileName.toString())) {
LOG.warn("Scheme file $fileName is not loaded because marked to delete")
LOG.warn("Scheme file \"$fileName\" is not loaded because marked to delete")
return null
}
@@ -367,7 +367,7 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
else {
// We don't load scheme with duplicated name - if we generate unique name for it, it will be saved then with new name.
// It is not what all can expect. Such situation in most cases indicates error on previous level, so, we just warn about it.
LOG.warn("Scheme file $fileName is not loaded because defines duplicated name ${scheme.getName()}")
LOG.warn("Scheme file \"$fileName\" is not loaded because defines duplicated name \"${scheme.getName()}\"")
}
return null
}
@@ -428,13 +428,13 @@ public class SchemeManagerImpl<T : Scheme, E : ExternalizableScheme>(private val
@suppress("UNCHECKED_CAST")
if (scheme is ExternalizableScheme) {
val state = getState(scheme as E)
if (state === BaseSchemeProcessor.State.NON_PERSISTENT) {
if (state == BaseSchemeProcessor.State.NON_PERSISTENT) {
continue
}
hasSchemes = true
if (state !== BaseSchemeProcessor.State.UNCHANGED) {
if (state != BaseSchemeProcessor.State.UNCHANGED) {
schemesToSave.add(scheme)
}
@@ -36,11 +36,10 @@ import org.jdom.Element
import org.jetbrains.annotations.TestOnly
import java.io.File
import java.io.IOException
import java.util.LinkedHashMap
import java.util.*
import java.util.concurrent.locks.ReentrantLock
import java.util.regex.Pattern
import kotlin.concurrent.withLock
import kotlin.reflect.jvm.java
/**
* If componentManager not specified, storage will not add file tracker (see VirtualFileTracker)
@@ -147,9 +146,9 @@ open class StateStorageManagerImpl(private val rootTagName: String,
*/
open fun expandNormalizedPath(path: String): String = expandMacros(path)
fun getOrCreateStorage(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, storageClass: Class<out StateStorage> = javaClass<StateStorage>(), @SuppressWarnings("deprecation") stateSplitter: Class<out StateSplitter> = javaClass<StateSplitterEx>()): StateStorage {
fun getOrCreateStorage(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, storageClass: Class<out StateStorage> = StateStorage::class.java, @SuppressWarnings("deprecation") stateSplitter: Class<out StateSplitter> = StateSplitterEx::class.java): StateStorage {
val collapsedPath = normalizeFileSpec(fileSpec)
val key = if (storageClass == javaClass<StateStorage>()) collapsedPath else storageClass.getName()
val key = if (storageClass == StateStorage::class.java) collapsedPath else storageClass.getName()
storageLock.withLock {
var storage = storages.get(key)
if (storage == null) {
@@ -184,7 +183,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
// overridden in upsource
protected open fun createStateStorage(storageClass: Class<out StateStorage>, collapsedPath: String, roamingType: RoamingType, @SuppressWarnings("deprecation") stateSplitter: Class<out StateSplitter>): StateStorage {
if (storageClass != javaClass<StateStorage>()) {
if (storageClass != StateStorage::class.java) {
val constructor = storageClass.getConstructors()[0]!!
constructor.setAccessible(true)
return constructor.newInstance(componentManager!!, this) as StateStorage
@@ -195,7 +194,7 @@ open class StateStorageManagerImpl(private val rootTagName: String,
}
val filePath = expandNormalizedPath(collapsedPath)
if (stateSplitter != javaClass<StateSplitter>() && stateSplitter != javaClass<StateSplitterEx>()) {
if (stateSplitter != StateSplitter::class.java && stateSplitter != StateSplitterEx::class.java) {
val storage = MyDirectoryStorage(this, File(filePath), ReflectionUtil.newInstance(stateSplitter))
virtualFileTracker?.put(filePath, storage)
return storage
@@ -67,7 +67,7 @@ class ApplicationStoreTest {
component.foo = "newValue"
componentStore.save(SmartList())
assertThat(streamProvider.data.get(RoamingType.DEFAULT)!!.get("proxy.xml")).isEqualTo("<application>\n" + " <component name=\"HttpConfigurable\">\n" + " <option name=\"foo\" value=\"newValue\" />\n" + " </component>\n" + "</application>")
assertThat(streamProvider.data.get(RoamingType.DEFAULT)!!.get("new.xml")).isEqualTo("<application>\n" + " <component name=\"A\" foo=\"newValue\" />\n" + "</application>")
}
@Test fun `load from stream provider`() {
@@ -75,8 +75,8 @@ class ApplicationStoreTest {
val streamProvider = MyStreamProvider()
val map = THashMap<String, String>()
val fileSpec = "proxy.xml"
map.put(fileSpec, "<application>\n <component name=\"HttpConfigurable\">\n <option name=\"foo\" value=\"newValue\" />\n </component>\n</application>")
val fileSpec = "new.xml"
map.put(fileSpec, "<application>\n <component name=\"A\" foo=\"newValue\" />\n</application>")
streamProvider.data.put(RoamingType.DEFAULT, map)
componentStore.storageManager.streamProvider = streamProvider
@@ -95,8 +95,8 @@ class ApplicationStoreTest {
}
private fun doRemoveDeprecatedStorageOnWrite(component: Foo) {
val oldFile = writeConfig("other.xml", "<application><component name=\"HttpConfigurable\"><option name=\"foo\" value=\"old\" /></component></application>")
writeConfig("proxy.xml", "<application><component name=\"HttpConfigurable\"><option name=\"foo\" value=\"new\" /></component></application>")
val oldFile = writeConfig("old.xml", "<application>${createComponentData("old")}</application>")
writeConfig("new.xml", "<application>${createComponentData("new")}</application>")
testAppConfig.refreshVfs()
@@ -109,6 +109,29 @@ class ApplicationStoreTest {
assertThat(oldFile).doesNotExist()
}
private fun createComponentData(foo: String) = """<component name="A" foo="$foo" />"""
@Test fun `remove data from deprecated storage if another component data exists`() {
val data = createComponentData("new")
val oldFile = writeConfig("old.xml", """<application>
<component name="OtherComponent" foo="old" />
${createComponentData("old")}
</application>""")
writeConfig("new.xml", "<application>$data</application>")
testAppConfig.refreshVfs()
val component = SeveralStoragesConfigured()
componentStore.initComponent(component, false)
assertThat(component.foo).isEqualTo("new")
saveStore()
assertThat(oldFile).hasContent("""<application>
<component name="OtherComponent" foo="old" />
</application>""")
}
@State(name = "A", storages = arrayOf(Storage(file = "a.xml")))
private open class A : PersistentStateComponent<Element> {
data class State(@Attribute var foo: String = "", @Attribute var bar: String = "")
@@ -118,7 +141,7 @@ class ApplicationStoreTest {
override fun getState() = state.serialize()
override fun loadState(state: Element) {
this.state = XmlSerializer.deserialize(state, javaClass<State>())!!
this.state = XmlSerializer.deserialize(state, State::class.java)!!
}
}
@@ -209,10 +232,11 @@ class ApplicationStoreTest {
}
abstract class Foo {
public var foo: String = "defaultValue"
@Attribute
var foo = "defaultValue"
}
@State(name = "HttpConfigurable", storages = arrayOf(Storage(file = "proxy.xml"), Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml", deprecated = true)))
@State(name = "A", storages = arrayOf(Storage(file = "new.xml"), Storage(file = StoragePathMacros.APP_CONFIG + "/old.xml", deprecated = true)))
class SeveralStoragesConfigured : Foo(), PersistentStateComponent<SeveralStoragesConfigured> {
override fun getState(): SeveralStoragesConfigured? {
return this
@@ -223,7 +247,7 @@ class ApplicationStoreTest {
}
}
@State(name = "HttpConfigurable", storages = arrayOf(Storage(file = "other.xml", deprecated = true), Storage(file = "${StoragePathMacros.APP_CONFIG}/proxy.xml")))
@State(name = "A", storages = arrayOf(Storage(file = "old.xml", deprecated = true), Storage(file = "${StoragePathMacros.APP_CONFIG}/new.xml")))
class ActualStorageLast : Foo(), PersistentStateComponent<ActualStorageLast> {
override fun getState() = this
@@ -5,28 +5,30 @@ import com.intellij.externalDependencies.ExternalDependenciesManager
import com.intellij.externalDependencies.ProjectExternalDependency
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.components.impl.stores.IComponentStore
import com.intellij.openapi.components.impl.stores.StateStorageManager
import com.intellij.openapi.components.service
import com.intellij.openapi.components.stateStore
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.testFramework.ProjectRule
import com.intellij.testFramework.RuleChain
import com.intellij.testFramework.TemporaryDirectory
import com.intellij.testFramework.deleteRecursively
import org.assertj.core.api.Assertions.assertThat
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExternalResource
import java.io.File
import java.nio.file.Paths
class DefaultProjectStoreTest {
companion object {
ClassRule val projectRule = ProjectRule()
@ClassRule val projectRule = ProjectRule()
}
private val tempDirManager = TemporaryDirectory()
private val requiredPlugins: List<ProjectExternalDependency> = listOf(DependencyOnPlugin("fake", "0", "1"))
private val requiredPlugins = listOf<ProjectExternalDependency>(DependencyOnPlugin("fake", "0", "1"))
private val ruleChain = RuleChain(
tempDirManager,
@@ -45,7 +47,7 @@ class DefaultProjectStoreTest {
app.doNotSave(isDoNotSave)
}
finally {
FileUtil.delete(File(app.stateStore.getStateStorageManager().expandMacros(StoragePathMacros.APP_CONFIG)))
Paths.get(app.stateStore.storageManager.expandMacros(StoragePathMacros.APP_CONFIG)).deleteRecursively()
}
}
},
@@ -63,11 +65,14 @@ class DefaultProjectStoreTest {
}
)
public Rule fun getChain(): RuleChain = ruleChain
@Rule fun getChain() = ruleChain
public Test fun `new project from default`() {
createProject(tempDirManager) {
@Test fun `new project from default`() {
createProjectAndUseInLoadComponentStateMode(tempDirManager) {
assertThat(it.service<ExternalDependenciesManager>().getAllDependencies()).isEqualTo(requiredPlugins)
}
}
}
}
val IComponentStore.storageManager: StateStorageManager
get() = getStateStorageManager()
@@ -47,7 +47,7 @@ class ModuleStoreTest {
private val tempDirManager = TemporaryDirectory()
private val ruleChain = RuleChain(tempDirManager, EdtRule(), ActiveStoreRule(projectRule), DisposeModulesRule(projectRule))
public Rule fun getChain(): RuleChain = ruleChain
@Rule fun getChain() = ruleChain
@Test fun `set option`() {
val moduleFile = runWriteAction {
@@ -32,11 +32,11 @@ import org.junit.Rule
import org.junit.Test
import java.io.File
fun createProject(tempDirManager: TemporaryDirectory, task: (Project) -> Unit) {
fun createProjectAndUseInLoadComponentStateMode(tempDirManager: TemporaryDirectory, task: (Project) -> Unit) {
createOrLoadProject(tempDirManager, task)
}
fun loadProject(tempDirManager: TemporaryDirectory, projectCreator: ((VirtualFile) -> String)? = null, task: (Project) -> Unit) {
fun loadAndUseProject(tempDirManager: TemporaryDirectory, projectCreator: ((VirtualFile) -> String)? = null, task: (Project) -> Unit) {
createOrLoadProject(tempDirManager, task, projectCreator)
}
@@ -51,20 +51,22 @@ private fun createOrLoadProject(tempDirManager: TemporaryDirectory, task: (Proje
}
val projectManager = ProjectManagerEx.getInstanceEx() as ProjectManagerImpl
var project = if (projectCreator == null) projectManager.newProject(null, filePath, true, false, false)!! else projectManager.loadProject(filePath)!!
try {
projectManager.openTestProject(project)
task(project)
}
finally {
projectManager.closeProject(project, false, true, false)
var project = if (projectCreator == null) projectManager.newProject(null, filePath, true, false)!! else projectManager.loadProject(filePath)!!
project.runInLoadComponentStateMode {
try {
projectManager.openTestProject(project)
task(project)
}
finally {
projectManager.closeProject(project, false, true, false)
}
}
}
}
class ProjectStoreTest {
companion object {
ClassRule val projectRule = ProjectRule()
@ClassRule val projectRule = ProjectRule()
}
val tempDirManager = TemporaryDirectory()
@@ -72,7 +74,7 @@ class ProjectStoreTest {
private val ruleChain = RuleChain(tempDirManager)
@Rule fun getChain() = ruleChain
Language("XML")
@Language("XML")
private val iprFileContent =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<project version=\"4\">\n" +
@@ -81,7 +83,7 @@ class ProjectStoreTest {
" </component>\n" +
"</project>"
State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE)))
@State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE)))
private class TestComponent : PersistentStateComponent<TestState> {
private var state: TestState? = null
@@ -94,8 +96,8 @@ class ProjectStoreTest {
data class TestState(var value: String = "default")
public Test fun directoryBasedStorage() {
loadProject(tempDirManager, {
@Test fun directoryBasedStorage() {
loadAndUseProject(tempDirManager, {
it.writeChild("${Project.DIRECTORY_STORE_FOLDER}/misc.xml", iprFileContent)
it.path
}) { project ->
@@ -112,8 +114,8 @@ class ProjectStoreTest {
}
}
public Test fun fileBasedStorage() {
loadProject(tempDirManager, { it.writeChild("test${ProjectFileType.DOT_DEFAULT_EXTENSION}", iprFileContent).path }) { project ->
@Test fun fileBasedStorage() {
loadAndUseProject(tempDirManager, { it.writeChild("test${ProjectFileType.DOT_DEFAULT_EXTENSION}", iprFileContent).path }) { project ->
test(project)
}
}
@@ -49,26 +49,26 @@ val FILE_SPEC = "REMOTE"
*/
class SchemeManagerTest {
companion object {
ClassRule val projectRule = ProjectRule()
@ClassRule val projectRule = ProjectRule()
}
private val tempDirManager = TemporaryDirectory()
public Rule fun getTemporaryFolder(): TemporaryDirectory = tempDirManager
@Rule fun getTemporaryFolder() = tempDirManager
private var localBaseDir: File? = null
private var remoteBaseDir: File? = null
private fun getTestDataPath() = PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/') + "/platform/platform-tests/testData/options"
public Test fun testLoadSchemes() {
@Test fun testLoadSchemes() {
doLoadSaveTest("options1", "1->first;2->second")
}
public Test fun testLoadSimpleSchemes() {
@Test fun testLoadSimpleSchemes() {
doLoadSaveTest("options", "1->1")
}
public Test fun testDeleteScheme() {
@Test fun testDeleteScheme() {
val manager = createAndLoad("options1")
manager.removeScheme(TestScheme("first"))
manager.save()
@@ -76,7 +76,7 @@ class SchemeManagerTest {
checkSchemes("2->second")
}
public Test fun testRenameScheme() {
@Test fun testRenameScheme() {
val manager = createAndLoad("options1")
val scheme = manager.findSchemeByName("first")
@@ -87,7 +87,7 @@ class SchemeManagerTest {
checkSchemes("2->second;renamed->renamed")
}
public Test fun testRenameScheme2() {
@Test fun testRenameScheme2() {
val manager = createAndLoad("options1")
val first = manager.findSchemeByName("first")
@@ -103,7 +103,7 @@ class SchemeManagerTest {
checkSchemes("1->1;2->2")
}
public Test fun testDeleteRenamedScheme() {
@Test fun testDeleteRenamedScheme() {
val manager = createAndLoad("options1")
val firstScheme = manager.findSchemeByName("first")
@@ -123,7 +123,7 @@ class SchemeManagerTest {
checkSchemes(localBaseDir!!, "", false)
}
public Test fun testDeleteAndCreateSchemeWithTheSameName() {
@Test fun testDeleteAndCreateSchemeWithTheSameName() {
val manager = createAndLoad("options1")
val firstScheme = manager.findSchemeByName("first")
assertThat(firstScheme).isNotNull()
@@ -134,7 +134,7 @@ class SchemeManagerTest {
checkSchemes("2->second;first->first")
}
public Test fun testGenerateUniqueSchemeName() {
@Test fun testGenerateUniqueSchemeName() {
val manager = createAndLoad("options1")
val scheme = TestScheme("first")
manager.addNewScheme(scheme, false)
@@ -146,7 +146,7 @@ class SchemeManagerTest {
FileUtil.writeToFile(file, _serialize().toByteArray())
}
public Test fun `different extensions`() {
@Test fun `different extensions`() {
val dir = tempDirManager.newDirectory()
val scheme = TestScheme("local", "true")
@@ -159,7 +159,7 @@ class SchemeManagerTest {
override fun getSchemeExtension() = ".icls"
}, null, dir)
schemesManager.loadSchemes()
assertThat(schemesManager.getAllSchemes()).containsOnly(scheme)
assertThat(schemesManager.allSchemes).containsOnly(scheme)
assertThat(File(dir, "1.icls")).isFile()
assertThat(File(dir, "1.xml")).isFile()
@@ -171,16 +171,16 @@ class SchemeManagerTest {
assertThat(File(dir, "1.xml")).doesNotExist()
}
public Test fun setSchemes() {
@Test fun setSchemes() {
val dir = tempDirManager.newDirectory()
val schemeManager = createSchemeManager(dir)
schemeManager.loadSchemes()
assertThat(schemeManager.getAllSchemes()).isEmpty()
assertThat(schemeManager.allSchemes).isEmpty()
val scheme = TestScheme("s1")
schemeManager.setSchemes(listOf(scheme))
val schemes = schemeManager.getAllSchemes()
val schemes = schemeManager.allSchemes
assertThat(schemes).containsOnly(scheme)
assertThat(File(dir, "s1.xml")).doesNotExist()
@@ -197,13 +197,13 @@ class SchemeManagerTest {
assertThat(dir).doesNotExist()
}
public Test fun `save only if scheme differs from bundled`() {
@Test fun `save only if scheme differs from bundled`() {
val dir = tempDirManager.newDirectory()
var schemeManager = createSchemeManager(dir)
val converter: (Element) -> TestScheme = { XmlSerializer.deserialize(it, javaClass<TestScheme>())!! }
val converter: (Element) -> TestScheme = { XmlSerializer.deserialize(it, TestScheme::class.java)!! }
val bundledPath = "/bundledSchemes/default"
schemeManager.loadBundledScheme(bundledPath, this, converter)
var schemes = schemeManager.getAllSchemes()
var schemes = schemeManager.allSchemes
val customScheme = TestScheme("default")
assertThat(schemes).containsOnly(customScheme)
@@ -214,7 +214,7 @@ class SchemeManagerTest {
schemeManager.setSchemes(listOf(customScheme))
assertThat(dir).doesNotExist()
schemes = schemeManager.getAllSchemes()
schemes = schemeManager.allSchemes
assertThat(schemes).containsOnly(customScheme)
customScheme.data = "foo"
@@ -225,11 +225,11 @@ class SchemeManagerTest {
schemeManager.loadBundledScheme(bundledPath, this, converter)
schemeManager.loadSchemes()
schemes = schemeManager.getAllSchemes()
schemes = schemeManager.allSchemes
assertThat(schemes).containsOnly(customScheme)
}
public Test fun `don't remove dir if no schemes but at least one non-hidden file exists`() {
@Test fun `don't remove dir if no schemes but at least one non-hidden file exists`() {
val dir = tempDirManager.newDirectory()
val schemeManager = createSchemeManager(dir)
@@ -251,7 +251,7 @@ class SchemeManagerTest {
assertThat(dir).isDirectory()
}
public Test fun `remove empty directory only if some file was deleted`() {
@Test fun `remove empty directory only if some file was deleted`() {
val dir = tempDirManager.newDirectory()
val schemeManager = createSchemeManager(dir)
schemeManager.loadSchemes()
@@ -269,16 +269,16 @@ class SchemeManagerTest {
assertThat(dir).doesNotExist()
}
public Test fun rename() {
@Test fun rename() {
val dir = tempDirManager.newDirectory()
val schemeManager = createSchemeManager(dir)
schemeManager.loadSchemes()
assertThat(schemeManager.getAllSchemes()).isEmpty()
assertThat(schemeManager.allSchemes).isEmpty()
val scheme = TestScheme("s1")
schemeManager.setSchemes(listOf(scheme))
val schemes = schemeManager.getAllSchemes()
val schemes = schemeManager.allSchemes
assertThat(schemes).containsOnly(scheme)
assertThat(File(dir, "s1.xml")).doesNotExist()
@@ -296,11 +296,11 @@ class SchemeManagerTest {
assertThat(File(dir, "s2.xml")).isFile()
}
public Test fun `path must not contains ROOT_CONFIG macro`() {
@Test fun `path must not contains ROOT_CONFIG macro`() {
assertThatThrownBy({ SchemesManagerFactory.getInstance().create<TestScheme, TestScheme>("\$ROOT_CONFIG$/foo", TestSchemesProcessor()) }).hasMessage("Path must not contains ROOT_CONFIG macro, corrected: foo")
}
public Test fun `path must be system-independent`() {
@Test fun `path must be system-independent`() {
assertThatThrownBy({SchemesManagerFactory.getInstance().create<TestScheme, TestScheme>("foo\\bar", TestSchemesProcessor())}).hasMessage("Path must be system-independent, use forward slash instead of backslash")
}
@@ -369,20 +369,20 @@ private fun checkSchemes(baseDir: File, expected: String, ignoreDeleted: Boolean
}
}
Tag("scheme")
public data class TestScheme(@Attribute private var name: String = "", @Attribute public var data: String? = null) : ExternalizableScheme {
@Tag("scheme")
data class TestScheme(@field:Attribute private var name: String = "", @field:Attribute var data: String? = null) : ExternalizableScheme {
override fun getName() = name
override Transient fun setName(newName: String) {
override @Transient fun setName(newName: String) {
name = newName
}
@suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
@Suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
override fun getExternalInfo() = null
}
public open class TestSchemesProcessor : BaseSchemeProcessor<TestScheme>() {
override fun readScheme(element: Element) = XmlSerializer.deserialize(element, javaClass<TestScheme>())
override fun readScheme(element: Element) = XmlSerializer.deserialize(element, TestScheme::class.java)
override fun writeScheme(scheme: TestScheme) = scheme._serialize()
}
@@ -390,7 +390,7 @@ public open class TestSchemesProcessor : BaseSchemeProcessor<TestScheme>() {
fun SchemeManagerImpl<*, *>.save() {
val errors = SmartList<Throwable>()
save(errors)
CompoundRuntimeException.doThrow(errors)
CompoundRuntimeException.throwIfNotEmpty(errors)
}
public fun <T : Any> T._serialize(filter: SerializationFilter? = SkipDefaultValuesSerializationFilters()): Element = XmlSerializer.serialize(this, filter)
@@ -19,8 +19,8 @@ import org.junit.runner.RunWith
import org.junit.runners.Suite
// All in package is very slow, so, we have to use Suite to speedup
RunWith(Suite::class)
Suite.SuiteClasses(
@RunWith(Suite::class)
@Suite.SuiteClasses(
ApplicationStoreTest::class,
ProjectStoreTest::class, DefaultProjectStoreTest::class,
ModuleStoreTest::class, ModuleStoreRenameTest::class,
@@ -24,7 +24,7 @@ import org.junit.Test
class XmlElementStorageTest {
@Test fun testGetStateSucceeded() {
val storage = MyXmlElementStorage(tag("root", tag("component", attr("name", "test"), tag("foo"))))
val state = storage.getState(this, "test", javaClass<Element>())
val state = storage.getState(this, "test", Element::class.java)
assertThat(state).isNotNull()
assertThat(state!!.getName()).isEqualTo("component")
assertThat(state.getChild("foo")).isNotNull()
@@ -32,7 +32,7 @@ class XmlElementStorageTest {
@Test fun `get state not succeeded`() {
val storage = MyXmlElementStorage(tag("root"))
val state = storage.getState(this, "test", javaClass<Element>())
val state = storage.getState(this, "test", Element::class.java)
assertThat(state).isNull()
}
@@ -125,6 +125,17 @@ public abstract class PsiDocumentManager {
*/
public abstract long getLastCommittedStamp(@NotNull Document document);
/**
* Returns the document for specified PsiFile intended to be used when working with committed PSI, e.g. outside dispatch thread.
* @param file the file for which the document is requested.
* @return an immutable document corresponding to the current PSI state. For committed documents, the contents and timestamp are equal to
* the ones of {@link #getDocument(PsiFile)}. For uncommitted documents, the text is {@link #getLastCommittedText(Document)} and
* the modification stamp is {@link #getLastCommittedStamp(Document)}.
* @since 143.* builds
*/
@Nullable
public abstract Document getLastCommittedDocument(@NotNull PsiFile file);
/**
* Returns the list of documents which have been modified but not committed.
*
@@ -47,6 +47,23 @@ public class ILazyParseableElementType extends IElementType {
super(debugName, language, register);
}
/**
* Parses the contents of the specified chameleon node and returns PsiBuilder.
* In future this method should deprecate all other parsing methods: parseContents(), doParseContents(), etc.
* It provides more flexible and CPU/memory efficient access to parser algorithms for all needs:
* editing, indexing and analysis.
* <p/>
*
* The parseContent() implementation in terms of parseLight() is just the following:
* {@code}parseLight().getTreeBuilt().getFirstChildNode(){@code}
*
* @param chameleon the node to parse.
* @return the parsed contents of the node in the form PsiBuilder.
*/
public PsiBuilder parseLight(ASTNode chameleon) {
throw new UnsupportedOperationException(String.valueOf(chameleon));
}
/**
* Parses the contents of the specified chameleon node and returns the AST tree
* representing the parsed contents.
@@ -54,13 +71,13 @@ public class ILazyParseableElementType extends IElementType {
* @param chameleon the node to parse.
* @return the parsed contents of the node.
*/
public ASTNode parseContents(final ASTNode chameleon) {
final PsiElement parentElement = chameleon.getTreeParent().getPsi();
assert parentElement != null : "Bad chameleon: " + chameleon;
public ASTNode parseContents(ASTNode chameleon) {
PsiElement parentElement = chameleon.getTreeParent().getPsi();
assert parentElement != null : "parent psi is null: " + chameleon;
return doParseContents(chameleon, parentElement);
}
protected ASTNode doParseContents(@NotNull final ASTNode chameleon, @NotNull final PsiElement psi) {
protected ASTNode doParseContents(@NotNull ASTNode chameleon, @NotNull PsiElement psi) {
Project project = psi.getProject();
Language languageForParser = getLanguageForParser(psi);
PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, null, languageForParser, chameleon.getChars());
@@ -123,8 +123,13 @@ public abstract class CachedValuesManager {
* @return The cached value
*/
public static <T> T getCachedValue(@NotNull final PsiElement psi, @NotNull final CachedValueProvider<T> provider) {
CachedValuesManager manager = getManager(psi.getProject());
return manager.getCachedValue(psi, manager.<T>getKeyForClass(provider.getClass()), new CachedValueProvider<T>() {
Key<CachedValue<T>> key = getKeyForClass(provider.getClass(), globalKeyForProvider);
CachedValue<T> value = psi.getUserData(key);
if (value != null) {
return value.getValue();
}
return getManager(psi.getProject()).getCachedValue(psi, key, new CachedValueProvider<T>() {
@Nullable
@Override
public Result<T> compute() {
@@ -138,8 +143,15 @@ public abstract class CachedValuesManager {
}
private final ConcurrentMap<String, Key<CachedValue>> keyForProvider = ContainerUtil.newConcurrentMap();
private static final ConcurrentMap<String, Key<CachedValue>> globalKeyForProvider = ContainerUtil.newConcurrentMap();
@NotNull
public <T> Key<CachedValue<T>> getKeyForClass(@NotNull Class<?> providerClass) {
return getKeyForClass(providerClass, keyForProvider);
}
@NotNull
private static <T> Key<CachedValue<T>> getKeyForClass(@NotNull Class<?> providerClass, ConcurrentMap<String, Key<CachedValue>> keyForProvider) {
String name = providerClass.getName();
assert name != null : providerClass + " doesn't have a name; can't be used for cache value provider";
Key<CachedValue> key = keyForProvider.get(name);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -17,6 +17,7 @@ package com.intellij.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.IndexNotReadyException;
import org.jetbrains.annotations.NotNull;
@@ -40,6 +41,7 @@ public final class ExecutorsQuery<Result, Parameter> extends AbstractQuery<Resul
protected boolean processResults(@NotNull final Processor<Result> consumer) {
for (QueryExecutor<Result, Parameter> executor : myExecutors) {
try {
ProgressManager.checkCanceled();
if (!executor.execute(myParameters, consumer)) {
return false;
}
@@ -19,9 +19,9 @@ import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.JBColor;
import com.intellij.util.ArrayUtil;
@@ -45,7 +45,7 @@ import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExternalizable, NamedComponent {
public class ApplicationInfoImpl extends ApplicationInfoEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.impl.ApplicationInfoImpl");
private String myCodeName = null;
@@ -187,6 +187,19 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
private static final String DEFAULT_PLUGINS_HOST = "http://plugins.jetbrains.com";
ApplicationInfoImpl() {
try {
Document doc = JDOMUtil.loadDocument(ApplicationInfoImpl.class, IDEA_PATH + ApplicationNamesInfo.getComponentName() + XML_EXTENSION);
loadState(doc.getRootElement());
}
catch (FileNotFoundException e) {
LOG.error("Resource is not in classpath or wrong platform prefix: " + System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY), e);
}
catch (Exception e) {
LOG.error(e);
}
}
@Override
public Calendar getBuildDate() {
return myBuildDate;
@@ -536,22 +549,11 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
public static ApplicationInfoEx getShadowInstance() {
if (ourShadowInstance == null) {
ourShadowInstance = new ApplicationInfoImpl();
try {
Document doc = JDOMUtil.loadDocument(ApplicationInfoImpl.class, IDEA_PATH + ApplicationNamesInfo.getComponentName() + XML_EXTENSION);
ourShadowInstance.readExternal(doc.getRootElement());
}
catch (FileNotFoundException e) {
LOG.error("Resource is not in classpath or wrong platform prefix: " + System.getProperty(PlatformUtils.PLATFORM_PREFIX_KEY), e);
}
catch (Exception e) {
LOG.error(e);
}
}
return ourShadowInstance;
}
@Override
public void readExternal(Element parentNode) throws InvalidDataException {
private void loadState(Element parentNode) {
Element versionElement = parentNode.getChild(ELEMENT_VERSION);
if (versionElement != null) {
myMajorVersion = versionElement.getAttributeValue(ATTRIBUTE_MAJOR);
@@ -845,11 +847,6 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
return new Color((int)rgb, rgb > 0xffffff);
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
throw new WriteExternalException();
}
@Override
public List<PluginChooserPage> getPluginChooserPages() {
return myPluginChooserPages;
@@ -860,12 +857,6 @@ public class ApplicationInfoImpl extends ApplicationInfoEx implements JDOMExtern
return PluginManagerCore.CORE_PLUGIN_ID.equals(pluginId) || ArrayUtil.contains(pluginId, myEssentialPluginsIds);
}
@Override
@NotNull
public String getComponentName() {
return ApplicationNamesInfo.getComponentName();
}
private static class UpdateUrlsImpl implements UpdateUrls {
private String myCheckingUrl;
private String myPatchesUrl;
@@ -210,7 +210,7 @@ public class PomModelImpl extends UserDataHolderBase implements PomModel {
finally {
DebugUtil.finishPsiModification();
}
if (!throwables.isEmpty()) CompoundRuntimeException.doThrow(throwables);
if (!throwables.isEmpty()) CompoundRuntimeException.throwIfNotEmpty(throwables);
}
}
}
@@ -38,7 +38,6 @@ import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubTree;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -456,8 +455,6 @@ public abstract class PsiAnchor {
private final int myIndex;
private final Language myLanguage;
private final IStubElementType myElementType;
private final short myCreationModCount;
private final short myCreationStamp;
private StubIndexReference(@NotNull final PsiFile file, final int index, @NotNull Language language, IStubElementType elementType) {
myLanguage = language;
@@ -465,16 +462,6 @@ public abstract class PsiAnchor {
myVirtualFile = file.getVirtualFile();
myProject = file.getProject();
myIndex = index;
myCreationModCount = getModCount();
myCreationStamp = (short)file.getModificationStamp();
}
private short getModCount() {
final PsiModificationTracker tracker = PsiManager.getInstance(getProject()).getModificationTracker();
if (myVirtualFile.getName().endsWith(".java")) {
return (short)tracker.getJavaStructureModificationCount();
}
return (short)tracker.getModificationCount();
}
@Override
@@ -521,11 +508,10 @@ public abstract class PsiAnchor {
}
catch (AssertionError e) {
String msg = e.getMessage();
msg += "\n current (java)modCount=" + getModCount() + "; creation (java)modCount=" + myCreationModCount;
if (file == null) {
msg += "\n no PSI file";
} else {
msg += "\n current file stamp=" + (short)file.getModificationStamp() + "; creation file stamp=" + myCreationStamp;
msg += "\n current file stamp=" + (short)file.getModificationStamp();
}
final Document document = FileDocumentManager.getInstance().getCachedDocument(myVirtualFile);
if (document != null) {
@@ -17,12 +17,15 @@
package com.intellij.psi.impl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootModificationTracker;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.util.CachedValueBase;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,8 +41,23 @@ public abstract class PsiCachedValue<T> extends CachedValueBase<T> {
}
@Override
protected void valueUpdated() {
myLastPsiTimeStamp = myManager.getModificationTracker().getModificationCount();
protected void valueUpdated(@Nullable Object[] dependencies) {
myLastPsiTimeStamp = hasOnlyPhysicalPsiDependencies(dependencies) ? myManager.getModificationTracker().getModificationCount() : -1;
}
private static boolean hasOnlyPhysicalPsiDependencies(@Nullable Object[] dependencies) {
return dependencies != null && dependencies.length > 0 && ContainerUtil.and(dependencies, new Condition<Object>() {
@Override
public boolean value(Object o) {
return o instanceof PsiElement && ((PsiElement)o).isValid() && ((PsiElement)o).isPhysical() ||
o instanceof ProjectRootModificationTracker ||
o instanceof PsiModificationTracker ||
o == PsiModificationTracker.MODIFICATION_COUNT ||
o == PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT ||
o == PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT ||
o == PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT;
}
});
}
@Nullable
@@ -55,10 +73,7 @@ public abstract class PsiCachedValue<T> extends CachedValueBase<T> {
@Override
protected boolean isDependencyOutOfDate(Object dependency, long oldTimeStamp) {
if (dependency instanceof PsiElement &&
myLastPsiTimeStamp == myManager.getModificationTracker().getModificationCount() &&
((PsiElement)dependency).isValid() &&
((PsiElement)dependency).isPhysical()) {
if (myLastPsiTimeStamp != -1 && myLastPsiTimeStamp == myManager.getModificationTracker().getModificationCount()) {
return false;
}
@@ -578,6 +578,13 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
return getLastCommittedDocument(document).getModificationStamp();
}
@Override
@Nullable
public Document getLastCommittedDocument(@NotNull PsiFile file) {
Document document = getDocument(file);
return document == null ? null : getLastCommittedDocument(document);
}
@NotNull
public DocumentEx getLastCommittedDocument(@NotNull Document document) {
if (document instanceof FrozenDocument) return (DocumentEx)document;
@@ -19,6 +19,7 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
@@ -45,6 +46,10 @@ public abstract class ResolveScopeManager {
@NotNull
public static GlobalSearchScope getElementResolveScope(@NotNull PsiElement element) {
PsiFile file = element.getContainingFile();
if (file != null) {
return getInstance(file.getProject()).getResolveScope(file);
}
return getInstance(element.getProject()).getResolveScope(element);
}
}
@@ -29,11 +29,10 @@ import com.intellij.psi.util.PsiUtilCore;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AnchorElementInfoFactory implements SmartPointerElementInfoFactory {
public class AnchorElementInfoFactory extends SmartPointerElementInfoFactory {
@Override
@Nullable
public SmartPointerElementInfo createElementInfo(@NotNull PsiElement element) {
PsiFile containingFile = element.getContainingFile();
public SmartPointerElementInfo createElementInfo(@NotNull PsiElement element, @NotNull PsiFile containingFile) {
if (element instanceof StubBasedPsiElement && containingFile instanceof PsiFileWithStubSupport) {
PsiFileWithStubSupport stubFile = (PsiFileWithStubSupport)containingFile;
StubTree stubTree = stubFile.getStubTree();
@@ -18,15 +18,16 @@ package com.intellij.psi.impl.smartPointers;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
public interface SmartPointerElementInfoFactory {
ExtensionPointName<SmartPointerElementInfoFactory> EP_NAME = ExtensionPointName.create("com.intellij.smartPointerElementInfoFactory");
public abstract class SmartPointerElementInfoFactory {
public static final ExtensionPointName<SmartPointerElementInfoFactory> EP_NAME = ExtensionPointName.create("com.intellij.smartPointerElementInfoFactory");
@Nullable
SmartPointerElementInfo createElementInfo(@NotNull PsiElement element);
public abstract SmartPointerElementInfo createElementInfo(@NotNull PsiElement element, @NotNull PsiFile containingFile);
}
@@ -183,7 +183,7 @@ class SmartPsiElementPointerImpl<E extends PsiElement> implements SmartPointerEx
}
for(SmartPointerElementInfoFactory factory: Extensions.getExtensions(SmartPointerElementInfoFactory.EP_NAME)) {
final SmartPointerElementInfo result = factory.createElementInfo(element);
final SmartPointerElementInfo result = factory.createElementInfo(element, containingFile);
if (result != null) return result;
}
@@ -182,11 +182,11 @@ public abstract class CachedValueBase<T> {
public T setValue(final CachedValueProvider.Result<T> result) {
Data<T> data = computeData(result);
setData(data);
valueUpdated();
valueUpdated(result.getDependencyItems());
return data.myValue;
}
protected void valueUpdated() {}
protected void valueUpdated(@Nullable Object[] dependencies) {}
public abstract boolean isFromMyProject(Project project);
@@ -227,7 +227,7 @@ public abstract class CachedValueBase<T> {
boolean reuse = alreadyComputed != null && isUpToDate(alreadyComputed);
Data<T> toReturn = cacheOrGetData(alreadyComputed, reuse ? null : data);
if (toReturn != null) {
valueUpdated();
valueUpdated(toReturn.myDependencies);
return toReturn.myValue;
}
}
@@ -16,12 +16,16 @@
package com.intellij.diff.merge;
import com.intellij.diff.DiffContext;
import com.intellij.diff.util.DiffUserDataKeysEx;
import com.intellij.diff.util.DiffUtil;
import com.intellij.diff.util.ThreeSide;
import com.intellij.openapi.diff.DiffBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,6 +36,10 @@ import java.util.List;
public class MergeUtil {
@NotNull
public static String getResolveActionTitle(@NotNull MergeResult result, @NotNull MergeRequest request, @NotNull MergeContext context) {
Function<MergeResult, String> getter = DiffUtil.getUserData(request, context, DiffUserDataKeysEx.MERGE_ACTION_CAPTIONS);
String message = getter != null ? getter.fun(result) : null;
if (message != null) return message;
switch (result) {
case CANCEL:
return "Abort";
@@ -95,9 +103,15 @@ public class MergeUtil {
}
public static boolean showExitWithoutApplyingChangesDialog(@NotNull JComponent component, @NotNull MergeRequest request, @NotNull MergeContext context) {
return Messages.showYesNoDialog(component.getRootPane(),
DiffBundle.message("merge.dialog.exit.without.applying.changes.confirmation.message"),
DiffBundle.message("cancel.visual.merge.dialog.title"), Messages.getQuestionIcon()) ==
Messages.YES;
String message = DiffBundle.message("merge.dialog.exit.without.applying.changes.confirmation.message");
String title = DiffBundle.message("cancel.visual.merge.dialog.title");
Couple<String> customMessage = DiffUtil.getUserData(request, context, DiffUserDataKeysEx.MERGE_CANCEL_MESSAGE);
if (customMessage != null) {
title = customMessage.first;
message = customMessage.second;
}
return Messages.showYesNoDialog(component.getRootPane(), message, title, Messages.getQuestionIcon()) == Messages.YES;
}
}
@@ -299,7 +299,7 @@ public class TextMergeChange extends ThreesideDiffChangeBase {
@Nullable
private GutterIconRenderer createApplyRenderer(@NotNull final Side side, final boolean modifier) {
if (isResolved(side)) return null;
Icon icon = isOnesideAppliedConflict() ? AllIcons.Diff.ArrowLeftDown : AllIcons.Diff.Arrow;
Icon icon = isOnesideAppliedConflict() ? DiffUtil.getArrowDownIcon(side) : DiffUtil.getArrowIcon(side);
return createIconRenderer(DiffBundle.message("merge.dialog.apply.change.action.name"), icon, isConflict(), new Runnable() {
@Override
public void run() {
@@ -417,7 +417,7 @@ public class TextMergeTool implements MergeTool {
return apply(mergeFragments, outputModificationStamp);
}
catch (DiffTooBigException e) {
return applyNotification(DiffNotifications.DIFF_TOO_BIG);
return applyNotification(DiffNotifications.createDiffTooBig());
}
catch (ProcessCanceledException e) {
throw e;
@@ -43,7 +43,7 @@ public class OnesideBinaryDiffViewer extends OnesideDiffViewer<BinaryEditorHolde
@Override
@NotNull
protected Runnable performRediff(@NotNull final ProgressIndicator indicator) {
JComponent notification = getSide().select(DiffNotifications.REMOVED_CONTENT, DiffNotifications.INSERTED_CONTENT);
JComponent notification = getSide().select(DiffNotifications.createRemovedContent(), DiffNotifications.createInsertedContent());
return applyNotification(notification);
}
@@ -77,7 +77,7 @@ public class TwosideBinaryDiffViewer extends TwosideDiffViewer<BinaryEditorHolde
final VirtualFile file1 = ((FileContent)contents.get(0)).getFile();
final VirtualFile file2 = ((FileContent)contents.get(1)).getFile();
if (!file1.isValid() || !file2.isValid()) {
return applyNotification(DiffNotifications.ERROR);
return applyNotification(DiffNotifications.createError());
}
final boolean equal = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
@@ -98,14 +98,14 @@ public class TwosideBinaryDiffViewer extends TwosideDiffViewer<BinaryEditorHolde
}
});
return applyNotification(equal ? DiffNotifications.EQUAL_CONTENTS : null);
return applyNotification(equal ? DiffNotifications.createEqualContents(): null);
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable e) {
LOG.error(e);
return applyNotification(DiffNotifications.ERROR);
return applyNotification(DiffNotifications.createError());
}
}
@@ -30,7 +30,6 @@ import com.intellij.diff.tools.util.base.*;
import com.intellij.diff.tools.util.side.TwosideTextDiffViewer;
import com.intellij.diff.util.*;
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
@@ -220,11 +219,9 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
List<AnAction> group = new ArrayList<AnAction>();
group.add(new ReplaceSelectedChangesAction(Side.LEFT, false));
group.add(new AppendSelectedChangesAction(Side.LEFT, false));
group.add(new ReplaceSelectedChangesAction(Side.RIGHT, false));
group.add(new AppendSelectedChangesAction(Side.LEFT, false));
group.add(new AppendSelectedChangesAction(Side.RIGHT, false));
group.add(new RevertSelectedChangesAction(Side.LEFT));
group.add(new RevertSelectedChangesAction(Side.RIGHT));
group.add(Separator.getInstance());
group.addAll(TextDiffViewerUtil.createEditorPopupActions());
@@ -383,7 +380,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
clearDiffPresentation();
if (isEqual) myPanel.addNotification(DiffNotifications.EQUAL_CONTENTS);
if (isEqual) myPanel.addNotification(DiffNotifications.createEqualContents());
TIntFunction separatorLines = myFoldingModel.getLineNumberConvertor();
myEditor.getGutterComponentEx().setLineNumberConvertor(mergeConverters(data.getLineConvertor1(), separatorLines),
@@ -648,7 +645,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
private abstract class ApplySelectedChangesActionBase extends AnAction implements DumbAware {
@NotNull protected final Side myModifiedSide;
private final boolean myShortcut;
protected final boolean myShortcut;
public ApplySelectedChangesActionBase(@NotNull Side modifiedSide, boolean shortcut) {
myModifiedSide = modifiedSide;
@@ -674,6 +671,7 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
return;
}
e.getPresentation().setText(getText());
e.getPresentation().setVisible(true);
e.getPresentation().setEnabled(isSomeChangeSelected());
}
@@ -714,6 +712,9 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
return false;
}
@NotNull
public abstract String getText();
@CalledWithWriteLock
protected abstract void apply(@NotNull List<UnifiedDiffChange> changes);
}
@@ -723,8 +724,19 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
super(focusedSide.other(), shortcut);
setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide")).getShortcutSet());
getTemplatePresentation().setText("Replace");
getTemplatePresentation().setIcon(focusedSide.select(AllIcons.Diff.ArrowRight, AllIcons.Diff.Arrow));
getTemplatePresentation().setIcon(DiffUtil.getArrowIcon(focusedSide));
}
@NotNull
@Override
public String getText() {
boolean bothEditable = isEditable(Side.LEFT, true) && isEditable(Side.RIGHT, true);
if (bothEditable) {
return myModifiedSide.select("Apply After", "Apply Before");
}
else {
return "Apply";
}
}
@Override
@@ -740,8 +752,19 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
super(focusedSide.other(), shortcut);
setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.AppendLeftSide", "Diff.AppendRightSide")).getShortcutSet());
getTemplatePresentation().setText("Insert");
getTemplatePresentation().setIcon(focusedSide.select(AllIcons.Diff.ArrowRightDown, AllIcons.Diff.ArrowLeftDown));
getTemplatePresentation().setIcon(DiffUtil.getArrowDownIcon(focusedSide));
}
@NotNull
@Override
public String getText() {
boolean bothEditable = isEditable(Side.LEFT, true) && isEditable(Side.RIGHT, true);
if (bothEditable) {
return myModifiedSide.select("Append Right Side", "Append Left Side");
}
else {
return "Append";
}
}
@Override
@@ -752,21 +775,6 @@ public class UnifiedDiffViewer extends ListenerDiffViewerBase {
}
}
private class RevertSelectedChangesAction extends ApplySelectedChangesActionBase {
public RevertSelectedChangesAction(@NotNull Side focusedSide) {
super(focusedSide, false);
getTemplatePresentation().setText("Revert");
getTemplatePresentation().setIcon(AllIcons.Diff.Remove);
}
@Override
protected void apply(@NotNull List<UnifiedDiffChange> changes) {
for (UnifiedDiffChange change : changes) {
replaceChange(change, myModifiedSide.other());
}
}
}
@CalledWithWriteLock
public void replaceChange(@NotNull UnifiedDiffChange change, @NotNull Side sourceSide) {
Side outputSide = sourceSide.other();
@@ -267,7 +267,7 @@ public class SimpleDiffChange {
@Nullable
private GutterIconRenderer createApplyRenderer(@NotNull final Side side) {
return createIconRenderer(side, "Replace", AllIcons.Diff.Arrow, new Runnable() {
return createIconRenderer(side, "Replace", DiffUtil.getArrowIcon(side), new Runnable() {
@Override
public void run() {
myViewer.replaceChange(SimpleDiffChange.this, side);
@@ -277,7 +277,7 @@ public class SimpleDiffChange {
@Nullable
private GutterIconRenderer createAppendRenderer(@NotNull final Side side) {
return createIconRenderer(side, "Insert", AllIcons.Diff.ArrowLeftDown, new Runnable() {
return createIconRenderer(side, "Insert", DiffUtil.getArrowDownIcon(side), new Runnable() {
@Override
public void run() {
myViewer.appendChange(SimpleDiffChange.this, side);
@@ -216,14 +216,14 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
return apply(new CompareData(lineFragments, isEqualContents));
}
catch (DiffTooBigException e) {
return applyNotification(DiffNotifications.DIFF_TOO_BIG);
return applyNotification(DiffNotifications.createDiffTooBig());
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable e) {
LOG.error(e);
return applyNotification(DiffNotifications.ERROR);
return applyNotification(DiffNotifications.createError());
}
}
@@ -235,7 +235,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
myFoldingModel.updateContext(myRequest, getFoldingModelSettings());
clearDiffPresentation();
if (data.isEqualContent()) myPanel.addNotification(DiffNotifications.EQUAL_CONTENTS);
if (data.isEqualContent()) myPanel.addNotification(DiffNotifications.createEqualContents());
if (data.getFragments() != null) {
for (LineFragment fragment : data.getFragments()) {
@@ -589,7 +589,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.ApplyLeftSide", "Diff.ApplyRightSide")).getShortcutSet());
getTemplatePresentation().setText("Replace");
getTemplatePresentation().setIcon(focusedSide.select(AllIcons.Diff.ArrowRight, AllIcons.Diff.Arrow));
getTemplatePresentation().setIcon(DiffUtil.getArrowIcon(focusedSide));
}
@Override
@@ -611,7 +611,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
setShortcutSet(ActionManager.getInstance().getAction(focusedSide.select("Diff.AppendLeftSide", "Diff.AppendRightSide")).getShortcutSet());
getTemplatePresentation().setText("Insert");
getTemplatePresentation().setIcon(focusedSide.select(AllIcons.Diff.ArrowRightDown, AllIcons.Diff.ArrowLeftDown));
getTemplatePresentation().setIcon(DiffUtil.getArrowDownIcon(focusedSide));
}
@Override
@@ -145,14 +145,14 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewerEx {
return apply(mergeFragments, comparisonPolicy);
}
catch (DiffTooBigException e) {
return applyNotification(DiffNotifications.DIFF_TOO_BIG);
return applyNotification(DiffNotifications.createDiffTooBig());
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable e) {
LOG.error(e);
return applyNotification(DiffNotifications.ERROR);
return applyNotification(DiffNotifications.createError());
}
}
@@ -25,19 +25,46 @@ import javax.swing.*;
import java.awt.*;
public class DiffNotifications {
@NotNull public static final JPanel INSERTED_CONTENT =
createNotification("Content added", TextDiffType.INSERTED.getColor(null));
@NotNull public static final JPanel REMOVED_CONTENT =
createNotification("Content removed", TextDiffType.DELETED.getColor(null));
@Deprecated @NotNull public static final JPanel INSERTED_CONTENT = createInsertedContent();
@Deprecated @NotNull public static final JPanel REMOVED_CONTENT = createRemovedContent();
@Deprecated @NotNull public static final JPanel EQUAL_CONTENTS = createEqualContents();
@Deprecated @NotNull public static final JPanel ERROR = createError();
@Deprecated @NotNull public static final JPanel OPERATION_CANCELED = createOperationCanceled();
@Deprecated @NotNull public static final JPanel DIFF_TOO_BIG = createDiffTooBig();
@NotNull public static final JPanel EQUAL_CONTENTS =
createNotification(DiffBundle.message("diff.contents.are.identical.message.text"));
@NotNull public static final JPanel ERROR =
createNotification("Can not calculate diff");
@NotNull public static final JPanel OPERATION_CANCELED =
createNotification("Can not calculate diff. Operation canceled.");
@NotNull public static final JPanel DIFF_TOO_BIG =
createNotification("Can not calculate diff. " + DiffTooBigException.MESSAGE);
@NotNull
public static JPanel createInsertedContent() {
return createNotification("Content added", TextDiffType.INSERTED.getColor(null));
}
@NotNull
public static JPanel createRemovedContent() {
return createNotification("Content removed", TextDiffType.DELETED.getColor(null));
}
@NotNull
public static JPanel createEqualContents() {
return createNotification(DiffBundle.message("diff.contents.are.identical.message.text"));
}
@NotNull
public static JPanel createError() {
return createNotification("Can not calculate diff");
}
@NotNull
public static JPanel createOperationCanceled() {
return createNotification("Can not calculate diff. Operation canceled.");
}
@NotNull
public static JPanel createDiffTooBig() {
return createNotification("Can not calculate diff. " + DiffTooBigException.MESSAGE);
}
//
// Impl
//
@NotNull
public static JPanel createNotification(@NotNull String text) {
@@ -15,9 +15,12 @@
*/
package com.intellij.diff.util;
import com.intellij.diff.merge.MergeResult;
import com.intellij.openapi.diff.DiffNavigationContext;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Key;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -53,4 +56,13 @@ public interface DiffUserDataKeysEx extends DiffUserDataKeys {
Key<JComponent> BOTTOM_PANEL = Key.create("Diff.BottomPanel"); // Could implement Disposable
Key<Boolean> SHOW_READ_ONLY_LOCK = Key.create("Diff.ShowReadOnlyLock");
//
// MergeContext / MergeRequest
//
// (title, message)
Key<Couple<String>> MERGE_CANCEL_MESSAGE = Key.create("Diff.MergeCancelMessage");
// null -> default
Key<Function<MergeResult, String>> MERGE_ACTION_CAPTIONS = Key.create("Diff.MergeActionCaptions");
}
@@ -32,6 +32,7 @@ import com.intellij.diff.requests.ContentDiffRequest;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.diff.tools.util.base.HighlightPolicy;
import com.intellij.diff.tools.util.base.IgnorePolicy;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
@@ -241,6 +242,20 @@ public class DiffUtil {
return editor != null ? editor.getCaretModel().getLogicalPosition() : new LogicalPosition(0, 0);
}
//
// Icons
//
@NotNull
public static Icon getArrowIcon(@NotNull Side sourceSide) {
return sourceSide.select(AllIcons.Diff.ArrowRight, AllIcons.Diff.Arrow);
}
@NotNull
public static Icon getArrowDownIcon(@NotNull Side sourceSide) {
return sourceSide.select(AllIcons.Diff.ArrowRightDown, AllIcons.Diff.ArrowLeftDown);
}
//
// UI
//
@@ -916,25 +931,13 @@ public class DiffUtil {
return false;
}
public static <T> T getUserData(@Nullable DiffRequest request, @Nullable DiffContext context, @NotNull Key<T> key) {
if (request != null) {
T data = request.getUserData(key);
public static <T> T getUserData(@Nullable UserDataHolder first, @Nullable UserDataHolder second, @NotNull Key<T> key) {
if (first != null) {
T data = first.getUserData(key);
if (data != null) return data;
}
if (context != null) {
T data = context.getUserData(key);
if (data != null) return data;
}
return null;
}
public static <T> T getUserData(@Nullable DiffContext context, @Nullable DiffRequest request, @NotNull Key<T> key) {
if (context != null) {
T data = context.getUserData(key);
if (data != null) return data;
}
if (request != null) {
T data = request.getUserData(key);
if (second != null) {
T data = second.getUserData(key);
if (data != null) return data;
}
return null;
@@ -44,13 +44,11 @@ import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
import com.intellij.testFramework.CompilerTester;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.PsiTestUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.*;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ThrowableRunnable;
import com.intellij.util.io.TestFileSystemItem;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
@@ -176,16 +174,11 @@ public abstract class ExternalSystemTestCase extends UsefulTestCase {
@Override
public void tearDown() throws Exception {
try {
edt(new Runnable() {
EdtTestUtil.runInEdtAndWait(new ThrowableRunnable<Throwable>() {
@Override
public void run() {
try {
CompilerTestUtil.disableExternalCompiler(myProject);
tearDownFixtures();
}
catch (Exception e) {
throw new RuntimeException(e);
}
public void run() throws Throwable {
CompilerTestUtil.disableExternalCompiler(myProject);
tearDownFixtures();
}
});
myProject = null;
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.search.searches;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
@@ -31,13 +32,13 @@ public class ReferenceDescriptor {
public ReferenceDescriptor fun(PsiReference psiReference) {
final PsiElement element = psiReference.getElement();
final PsiFile file = element.getContainingFile();
return new ReferenceDescriptor(file, element.getTextRange().getStartOffset() + psiReference.getRangeInElement().getStartOffset());
return new ReferenceDescriptor(file.getViewProvider().getVirtualFile(), element.getTextRange().getStartOffset() + psiReference.getRangeInElement().getStartOffset());
}
};
private final PsiFile file;
private final VirtualFile file;
private final int offset;
private ReferenceDescriptor(@NotNull PsiFile file, int offset) {
private ReferenceDescriptor(@NotNull VirtualFile file, int offset) {
this.file = file;
this.offset = offset;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,18 +15,18 @@
*/
package com.intellij.usageView;
import com.intellij.openapi.components.NamedComponent;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.colors.EditorColorsUtil;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.util.ui.UIUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class UsageTreeColorsScheme implements NamedComponent, JDOMExternalizable {
@State(name = "FindViewColorsScheme", defaultStateAsResource = true, storages = {})
public class UsageTreeColorsScheme implements PersistentStateComponent<Element> {
private EditorColorsScheme myColorsScheme;
/**
@@ -39,26 +39,21 @@ public class UsageTreeColorsScheme implements NamedComponent, JDOMExternalizable
return ServiceManager.getService(UsageTreeColorsScheme.class);
}
@Override
@NotNull
public String getComponentName() {
return "FindViewColorsScheme";
}
public EditorColorsScheme getScheme() {
return myColorsScheme;
}
@Nullable
@Override
public void readExternal(Element element) {
if (myColorsScheme == null) {
myColorsScheme = (EditorColorsScheme)EditorColorsUtil.getColorSchemeForBackground(UIUtil.getTreeTextBackground()).clone();
}
myColorsScheme.readExternal(element);
public Element getState() {
return null;
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
throw new WriteExternalException();
public void loadState(Element state) {
if (myColorsScheme == null) {
myColorsScheme = (EditorColorsScheme)EditorColorsUtil.getColorSchemeForBackground(UIUtil.getTreeTextBackground()).clone();
}
myColorsScheme.readExternal(state);
}
}
@@ -23,14 +23,12 @@ import com.intellij.openapi.options.colors.AttributesDescriptor;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.CollectionComboBoxModel;
import com.intellij.ui.ColorPanel;
import com.intellij.ui.HyperlinkAdapter;
import com.intellij.ui.ListCellRendererWrapper;
import com.intellij.ui.*;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.FontUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -38,8 +36,8 @@ import javax.swing.event.HyperlinkEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.Map;
import java.util.*;
import java.util.List;
/**
* @author cdr
@@ -70,6 +68,7 @@ public class ColorAndFontDescriptionPanel extends JPanel {
myEffectsMap = Collections.unmodifiableMap(map);
}
private JComboBox myEffectsCombo;
private final EffectsComboModel myEffectsModel;
private JBCheckBox myCbBold;
private JBCheckBox myCbItalic;
@@ -83,7 +82,10 @@ public class ColorAndFontDescriptionPanel extends JPanel {
add(myPanel, BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(4, 0, 4, 4));
myEffectsCombo.setModel(new CollectionComboBoxModel(ContainerUtil.newArrayList(myEffectsMap.keySet())));
myEffectsModel = new EffectsComboModel(ContainerUtil.newArrayList(myEffectsMap.keySet()));
//noinspection unchecked
myEffectsCombo.setModel(myEffectsModel);
//noinspection unchecked
myEffectsCombo.setRenderer(new ListCellRendererWrapper<String>() {
@Override
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
@@ -152,7 +154,7 @@ public class ColorAndFontDescriptionPanel extends JPanel {
colorPanel.setSelectedColor(color);
}
else {
colorPanel.setSelectedColor(Color.white);
colorPanel.setSelectedColor(JBColor.WHITE);
}
colorPanel.setEnabled(isChecked);
}
@@ -189,7 +191,7 @@ public class ColorAndFontDescriptionPanel extends JPanel {
if (description.isEffectsColorEnabled() && description.isEffectsColorChecked()) {
myEffectsCombo.setEnabled(true);
myEffectsCombo.getModel().setSelectedItem(ContainerUtil.reverseMap(myEffectsMap).get(effectType));
myEffectsModel.setEffectName(ContainerUtil.reverseMap(myEffectsMap).get(effectType));
}
else {
myEffectsCombo.setEnabled(false);
@@ -293,4 +295,20 @@ public class ColorAndFontDescriptionPanel extends JPanel {
description.apply(scheme);
}
}
private static class EffectsComboModel extends CollectionComboBoxModel<String> {
public EffectsComboModel(List<String> names) {
super(names);
}
/**
* Set the current effect name when a text attribute selection changes without notifying the listeners since otherwise it will
* be considered as an actual change and lead to unnecessary evens including 'read-only scheme' check.
*
* @param effectName
*/
public void setEffectName(@NotNull String effectName) {
mySelection = effectName;
}
}
}
@@ -73,6 +73,10 @@ public class LegacyCompletionContributor extends CompletionContributor {
completionData.completeReference(reference, lookupSet, parameters.getPosition(), parameters.getOriginalFile());
for (final LookupElement item : lookupSet) {
if (resultSet.getPrefixMatcher().prefixMatches(item)) {
if (!item.isValid()) {
LOG.error(completionData + " has returned an invalid lookup element " + item + " of " + item.getClass() +
" in " + parameters.getOriginalFile() + " of " + parameters.getOriginalFile().getClass());
}
hasVariants.set(true);
resultSet.addElement(item);
}
@@ -125,7 +125,8 @@ public class CompletionServiceImpl extends CompletionService{
@Override
public void addElement(@NotNull final LookupElement element) {
if (!element.isValid()) {
LOG.error("Invalid lookup element: " + element);
LOG.error("Invalid lookup element: " + element + " of " + element.getClass() +
" in " + myParameters.getOriginalFile() + " of " + myParameters.getOriginalFile().getClass());
return;
}
@@ -22,7 +22,6 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.CheckboxTree;
@@ -144,15 +143,13 @@ class LiveTemplateTree extends CheckboxTree implements DataProvider, CopyProvide
assert buffer != null;
try {
for (Element templateElement : JDOMUtil.load(new StringReader("<root>" + buffer + "</root>")).getChildren()) {
try {
TemplateImpl template = TemplateSettings.readTemplateFromElement(group.getName(), templateElement, getClass().getClassLoader());
myConfigurable.addTemplate(template);
}
catch (InvalidDataException ignore) { }
for (Element templateElement : JDOMUtil.load(new StringReader("<root>" + buffer + "</root>")).getChildren(TemplateSettings.TEMPLATE)) {
myConfigurable.addTemplate(TemplateSettings.readTemplateFromElement(group.getName(), templateElement, getClass().getClassLoader()));
}
}
catch (JDOMException ignore) { }
catch (IOException ignore) { }
catch (JDOMException ignore) {
}
catch (IOException ignore) {
}
}
}

Some files were not shown because too many files have changed in this diff Show More