diff --git a/.idea/modules.xml b/.idea/modules.xml
index 5a29a2a547ff..7d37961600ad 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -64,6 +64,7 @@
+
diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java
index 0351ca66c6ab..bc63355134a6 100644
--- a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java
+++ b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java
@@ -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() {
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java
new file mode 100644
index 000000000000..8c37fda39f52
--- /dev/null
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/ForceEarlyReturnAction.java
@@ -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);
+ }
+ }
+}
diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java
index 5b4048129cba..8e1dc5075727 100644
--- a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java
+++ b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java
@@ -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 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 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) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
index b4cfc1680d26..3a8c2b6bac48 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java
@@ -397,6 +397,7 @@ public class JavaStackFrame extends XStackFrame {
}
}
+ @NotNull
public StackFrameProxyImpl getStackFrameProxy() {
return myDescriptor.getFrameProxy();
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java
index 57b1a44bb3c5..8956138882d9 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/BlockStatementEvaluator.java
@@ -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);
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java
index 1e48568a8dd8..c7de16e59362 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java
@@ -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;
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java
index 1064d0747b2b..4a7eee833d38 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java
@@ -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) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java
index a48e960008ee..31c3aab00d42 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/IfStatementEvaluator.java
@@ -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;
}
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/JdiProxy.java b/java/debugger/impl/src/com/intellij/debugger/jdi/JdiProxy.java
index ab8a3ce5ec26..1552cdeae648 100644
--- a/java/debugger/impl/src/com/intellij/debugger/jdi/JdiProxy.java
+++ b/java/debugger/impl/src/com/intellij/debugger/jdi/JdiProxy.java
@@ -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();
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
index e24067f711d3..957ada3482a2 100644
--- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java
@@ -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 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;
diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java
index 7b8b1d1f9df0..1f53846f3ce3 100644
--- a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java
@@ -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();
diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java
index c2211fe1c648..57fadf168a81 100644
--- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java
@@ -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) {
diff --git a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java
index d8c1a40a14bb..f0a17365a9b5 100644
--- a/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java
+++ b/java/execution/impl/src/com/intellij/execution/impl/JavaScratchRunConfigurationExtension.java
@@ -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 SCRATCH_FILE_ID = Key.create("_scratch_file_id_");
diff --git a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
index a236694c6c4f..fa799ed3dbf8 100644
--- a/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
+++ b/java/idea-ui/src/com/intellij/util/descriptors/impl/ConfigFileContainerImpl.java
@@ -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 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 descriptorsMap) {
- Set toDelete = new HashSet(myConfigFiles.values());
- Set added = new HashSet();
+ public void updateDescriptors(@NotNull MultiValuesMap descriptorsMap) {
+ Set toDelete = myConfigFiles.isEmpty() ? Collections.emptySet() : new HashSet(myConfigFiles.values());
+ Set added = null;
for (Map.Entry> entry : descriptorsMap.entrySet()) {
ConfigFileMetaData metaData = entry.getKey();
@@ -142,8 +137,7 @@ public class ConfigFileContainerImpl extends SimpleModificationTracker implement
final Collection 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();
+ }
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();
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index 738e467c520a..2559f4e9f3a5 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -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 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 myElementStack = new Stack();
/**
@@ -61,50 +63,45 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
*/
private FactoryMap 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() {
@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();
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 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);
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
index a88985f0fb09..1adc7fa781d2 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
@@ -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 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 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);
}
diff --git a/java/java-analysis-impl/src/com/intellij/psi/impl/FindSuperElementsHelper.java b/java/java-analysis-impl/src/com/intellij/psi/impl/FindSuperElementsHelper.java
index 7d5bfda6dfec..8a468bd71614 100644
--- a/java/java-analysis-impl/src/com/intellij/psi/impl/FindSuperElementsHelper.java
+++ b/java/java-analysis-impl/src/com/intellij/psi/impl/FindSuperElementsHelper.java
@@ -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() {
@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;
diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
index 29da83455ee1..a52f6b467f75 100644
--- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
+++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
@@ -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;
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java
index b2c76903ae03..2677ec64de8a 100644
--- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java
+++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImportListElementInfoFactory.java
@@ -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;
}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaOutOfSourcesResolveScopeProvider.java b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaOutOfSourcesResolveScopeProvider.java
new file mode 100644
index 000000000000..a3e9e87f3a4c
--- /dev/null
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/file/impl/JavaOutOfSourcesResolveScopeProvider.java
@@ -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;
+ }
+}
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java
index 7846f74651e2..b6f1d08b2111 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java
@@ -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() {
@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 processor = new ReadActionProcessor() {
@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() {
@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> classes = new HashMap>();
for (final PsiReferenceList referenceList : candidates) {
- ProgressIndicatorProvider.checkCanceled();
+ ProgressManager.checkCanceled();
final PsiClass candidate = (PsiClass)ApplicationManager.getApplication().runReadAction(new Computable() {
@Override
public PsiElement compute() {
@@ -139,6 +140,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor sameNamedClasses : classes.values()) {
+ ProgressManager.checkCanceled();
if (!processSameNamedClasses(consumer, sameNamedClasses, jarFile)) return false;
}
}
@@ -155,7 +157,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor() {
@@ -210,6 +213,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor 1) {
for (PsiClass sameNamedClass : sameNamedClasses) {
+ ProgressManager.checkCanceled();
boolean fromSameJar = Comparing.equal(getJarFile(sameNamedClass), jarFile);
if (fromSameJar) {
sameJarClassFound = true;
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
index 8ab27b1b4286..0bc09d7b52f7 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
@@ -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 T resolveInReadAction(@NotNull Project p, Computable computable) {
+ static T resolveInReadAction(@NotNull Project p, @NotNull Computable computable) {
return ApplicationManager.getApplication().isReadAccessAllowed() ? computable.compute() : DumbService.getInstance(p).runReadActionInSmartMode(computable);
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
index ad6bd78e6165..6a3d5c98ab40 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
@@ -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();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/JavaConstantExpressionEvaluator.java b/java/java-psi-impl/src/com/intellij/psi/impl/JavaConstantExpressionEvaluator.java
index 1dfb3b57532e..73b72a0943b0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/JavaConstantExpressionEvaluator.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/JavaConstantExpressionEvaluator.java
@@ -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) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java
index e56f53cbfbdf..97b43b4db570 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileImpl.java
@@ -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() {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java
index 8a1f32ce83f4..642cbe6fcd79 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/SymbolCollectingProcessor.java
@@ -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 myResult = new MostlySingularMultiMap();
private PsiElement myCurrentFileContext = null;
+ private PsiAnchor myCurrentContextAnchor = null;
@Override
public T getHint(@NotNull Key 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
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java
index 123e750e0a1a..0630b125125a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/VariableResolverProcessor.java
@@ -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(), place, placeFile);
+ super(place.getReferenceName(), ourFilter, new PsiConflictResolver[]{new JavaVariableConflictResolver()}, new SmartList(), 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 getHint(@NotNull Key hintKey) {
if (hintKey == ElementClassHint.KEY) {
+ //noinspection unchecked
return (T)this;
}
diff --git a/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml b/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml
index 8184735d55cf..9cd23b0df42b 100644
--- a/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml
+++ b/java/java-tests/testData/inspection/unusedLibrary/simple/expected.xml
@@ -1,7 +1,7 @@
- testSimple_0.iml
+ testSimple.iml
Unused library
Unused library 'JUnit'
diff --git a/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java b/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java
index 1aecb65638f9..39d4f6380f0f 100644
--- a/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java
+++ b/java/java-tests/testSrc/com/intellij/execution/ConfigurationsTest.java
@@ -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)));
diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterMultilineMethodCallParamsTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterMultilineMethodCallParamsTest.java
index d80b29c25191..1596c605d986 100644
--- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterMultilineMethodCallParamsTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterMultilineMethodCallParamsTest.java
@@ -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(
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MultipleJdksMoveClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MultipleJdksMoveClassTest.java
index e88d816cd7b2..b2e9b9e190a8 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/MultipleJdksMoveClassTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/MultipleJdksMoveClassTest.java
@@ -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;
diff --git a/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java b/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java
index cddb960084d4..9cf5c67a3b05 100644
--- a/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java
+++ b/java/java-tests/testSrc/com/intellij/roots/RootsChangedTest.java
@@ -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();
diff --git a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
index 60c06b99de2c..5b4f69d6a4ab 100644
--- a/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
+++ b/java/testFramework/src/com/intellij/compiler/CompilerTestUtil.java
@@ -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 modulesToRestore = new ArrayList();
- 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() {
+ @Override
+ public void run() throws Throwable {
+ JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
+ AccessToken token = WriteAction.start();
+ try {
+ Sdk internalJdk = table.getInternalJdk();
+ List modulesToRestore = new SmartList();
+ 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);
+ }
}
}
diff --git a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java
index ade8358e30dd..68426748e81a 100644
--- a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java
+++ b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java
@@ -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 myException = new SmartList();
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);
}
}
diff --git a/java/testFramework/src/com/intellij/execution/ExecutionTestCase.java b/java/testFramework/src/com/intellij/execution/ExecutionTestCase.java
index 81a5ffe6fb3e..339e490c7a86 100644
--- a/java/testFramework/src/com/intellij/execution/ExecutionTestCase.java
+++ b/java/testFramework/src/com/intellij/execution/ExecutionTestCase.java
@@ -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() {
@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 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() {
@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());
diff --git a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
index 2d6859cb83e6..a2139b376f95 100644
--- a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
+++ b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
@@ -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 myModulesToDispose = new ArrayList();
@@ -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 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();
+ }
+ 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() {
- @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 moduleConsumer) {
final Ref 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 {
diff --git a/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java
index d78c00776528..26153fac55c5 100644
--- a/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java
+++ b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java
@@ -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
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java
index f527677f23e6..9ee51cf765af 100644
--- a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java
@@ -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 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() {
+ @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) {
diff --git a/java/testFramework/testFramework-java.iml b/java/testFramework/testFramework-java.iml
index 2ffc1004c739..90a2a5d0ce1f 100644
--- a/java/testFramework/testFramework-java.iml
+++ b/java/testFramework/testFramework-java.iml
@@ -13,7 +13,7 @@
-
+
diff --git a/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java b/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java
index 4bfee3617614..13f37ce525e5 100644
--- a/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java
+++ b/platform/analysis-api/src/com/intellij/profile/DefaultProjectProfileManager.java
@@ -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;
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java
index 75caebfab82d..b0c423d7c3f9 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java
@@ -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 {
+public class SeverityRegistrar implements Comparator {
@NonNls private static final String INFO_TAG = "info";
@NonNls private static final String COLOR_ATTRIBUTE = "color";
private final Map myMap = ContainerUtil.newConcurrentMap();
@@ -132,7 +131,6 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator list = getOrderAsList(getOrderMap());
for (HighlightSeverity severity : list) {
diff --git a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java
index f615cba2f29b..29e0cf6c39e6 100644
--- a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java
+++ b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java
@@ -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 referencesList = reparse(str, myStartInElement);
-
+ List referencesList = reparse(myPathStringNonTrimmed, myStartInElement);
myReferences = referencesList.toArray(new FileReference[referencesList.size()]);
}
protected List 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 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&.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;
diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt
index f032106892ea..e9797d72be3f 100644
--- a/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt
+++ b/platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt
@@ -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())
+ 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"))
}
\ No newline at end of file
diff --git a/platform/built-in-server/src/org/jetbrains/builtInWebServer/NetService.kt b/platform/built-in-server/src/org/jetbrains/builtInWebServer/NetService.kt
index 70f69ff5660e..3cd342a7f496 100644
--- a/platform/built-in-server/src/org/jetbrains/builtInWebServer/NetService.kt
+++ b/platform/built-in-server/src/org/jetbrains/builtInWebServer/NetService.kt
@@ -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())
+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 = object : AsyncValueLoader() {
diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt
index ddd0bb4c309a..b5c418747977 100644
--- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt
+++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiDecoder.kt
@@ -76,7 +76,7 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer, private
override fun channelInactive(context: ChannelHandlerContext) {
try {
- if (!dataBuffers.isEmpty()) {
+ if (!dataBuffers.isEmpty) {
dataBuffers.forEachEntry(object : TIntObjectProcedure {
override fun execute(a: Int, buffer: ByteBuf): Boolean {
try {
@@ -92,7 +92,7 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer, private
}
}
finally {
- super.channelInactive(context)
+ super.channelInactive(context)
}
}
@@ -136,8 +136,10 @@ class FastCgiDecoder(private val errorOutputConsumer: Consumer, 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, private
}
}
- else -> LOG.error("Unknown type " + type)
+ else -> LOG.error("Unknown type $type")
}
return null
}
diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiRequest.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiRequest.kt
index 495ef9b6e74f..7b1c62c74fa1 100644
--- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiRequest.kt
+++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiRequest.kt
@@ -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)
}
}
diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt
index d43952c3f582..e7d54e0210f7 100644
--- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt
+++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt
@@ -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())
+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
}
diff --git a/platform/built-in-server/testSrc/TestManager.kt b/platform/built-in-server/testSrc/TestManager.kt
index 03181ce3ce18..f990a1c751d7 100644
--- a/platform/built-in-server/testSrc/TestManager.kt
+++ b/platform/built-in-server/testSrc/TestManager.kt
@@ -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())
+ annotation = description.getAnnotation(TestDescriptor::class.java)
if (annotation == null) {
return
}
diff --git a/platform/configuration-store-impl/src/ApplicationStoreImpl.kt b/platform/configuration-store-impl/src/ApplicationStoreImpl.kt
index e36c1e4aba9c..e3f7c89d51a1 100644
--- a/platform/configuration-store-impl/src/ApplicationStoreImpl.kt
+++ b/platform/configuration-store-impl/src/ApplicationStoreImpl.kt
@@ -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}")
diff --git a/platform/configuration-store-impl/src/ComponentStoreImpl.kt b/platform/configuration-store-impl/src/ComponentStoreImpl.kt
index 39a54ea75114..2218288cd495 100644
--- a/platform/configuration-store-impl/src/ComponentStoreImpl.kt
+++ b/platform/configuration-store-impl/src/ComponentStoreImpl.kt
@@ -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())
+private val LOG = Logger.getInstance(ComponentStoreImpl::class.java)
/**
* Note: 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, 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())?.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(), 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 initPersistentComponent(stateSpec: State, component: PersistentStateComponent, changedStorages: Set?, reloadData: Boolean): String? {
- if (optimizeTestLoading()) {
+ private fun initPersistentComponent(stateSpec: State, component: PersistentStateComponent, changedStorages: Set?, 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) = !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>) {
val stateSpec = StoreUtil.getStateSpecOrError(componentClass)
+ @suppress("UNCHECKED_CAST")
val component = components.get(stateSpec.name) as PersistentStateComponent?
if (component != null) {
initPersistentComponent(stateSpec, component, emptySet(), true)
@@ -364,6 +382,7 @@ abstract class ComponentStoreImpl : IComponentStore {
}
private fun reloadState(componentName: String, changedStorages: Set): Boolean {
+ @suppress("UNCHECKED_CAST")
val component = components.get(componentName) as PersistentStateComponent?
if (component == null) {
return false
@@ -447,4 +466,8 @@ abstract class ComponentStoreImpl : IComponentStore {
return errors
}
}
+}
+
+enum class StateLoadPolicy {
+ LOAD, LOAD_ONLY_DEFAULT, NOT_LOAD
}
\ No newline at end of file
diff --git a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt
index 7a619fee2f95..11f74ad2a33f 100644
--- a/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt
+++ b/platform/configuration-store-impl/src/DefaultProjectStoreImpl.kt
@@ -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().project = project
}
diff --git a/platform/configuration-store-impl/src/ModuleStoreImpl.kt b/platform/configuration-store-impl/src/ModuleStoreImpl.kt
index 40839c4d9831..6d3258086673 100644
--- a/platform/configuration-store-impl/src/ModuleStoreImpl.kt
+++ b/platform/configuration-store-impl/src/ModuleStoreImpl.kt
@@ -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
}
\ No newline at end of file
diff --git a/platform/configuration-store-impl/src/PlatformProjectStoreClassProvider.kt b/platform/configuration-store-impl/src/PlatformProjectStoreClassProvider.kt
index b1a94c0ab065..3b3662c3d735 100644
--- a/platform/configuration-store-impl/src/PlatformProjectStoreClassProvider.kt
+++ b/platform/configuration-store-impl/src/PlatformProjectStoreClassProvider.kt
@@ -20,6 +20,6 @@ import com.intellij.openapi.project.impl.ProjectStoreClassProvider
class PlatformProjectStoreClassProvider : ProjectStoreClassProvider {
override fun getProjectStoreClass(isDefaultProject: Boolean): Class {
- return if (isDefaultProject) javaClass() else javaClass()
+ return if (isDefaultProject) DefaultProjectStoreImpl::class.java else ProjectStoreImpl::class.java
}
}
\ No newline at end of file
diff --git a/platform/configuration-store-impl/src/ProjectStoreImpl.kt b/platform/configuration-store-impl/src/ProjectStoreImpl.kt
index 92d7d2b22143..ae6900ab4570 100644
--- a/platform/configuration-store-impl/src/ProjectStoreImpl.kt
+++ b/platform/configuration-store-impl/src/ProjectStoreImpl.kt
@@ -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.doSave(saveSessions, readonlyFiles, errors)
- val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(javaClass(), 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) {
- val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(javaClass(), project)
+ val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification::class.java, project)
if (notifications.isEmpty()) {
Notifications.Bus.notify(UnableToSaveProjectNotification(project, readOnlyFiles), project)
}
diff --git a/platform/configuration-store-impl/src/ProjectWithModulesStoreImpl.kt b/platform/configuration-store-impl/src/ProjectWithModulesStoreImpl.kt
index ee88d24f9a4a..da1e7c58b262 100644
--- a/platform/configuration-store-impl/src/ProjectWithModulesStoreImpl.kt
+++ b/platform/configuration-store-impl/src/ProjectWithModulesStoreImpl.kt
@@ -28,7 +28,7 @@ import com.intellij.openapi.vfs.VirtualFile
class PlatformLangProjectStoreClassProvider : ProjectStoreClassProvider {
override fun getProjectStoreClass(isDefaultProject: Boolean): Class {
- return if (isDefaultProject) javaClass() else javaClass()
+ return if (isDefaultProject) DefaultProjectStoreImpl::class.java else ProjectWithModulesStoreImpl::class.java
}
}
diff --git a/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt b/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt
index de4019a335ff..09117da34363 100644
--- a/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt
+++ b/platform/configuration-store-impl/src/SchemeManagerFactoryImpl.kt
@@ -83,7 +83,7 @@ public abstract class SchemeManagerFactoryBase : SchemesManagerFactory(), Settin
}
}
- CompoundRuntimeException.doThrow(errors)
+ CompoundRuntimeException.throwIfNotEmpty(errors)
}
}
diff --git a/platform/configuration-store-impl/src/SchemeManagerImpl.kt b/platform/configuration-store-impl/src/SchemeManagerImpl.kt
index 20846da1dbbe..eb72ce1b69fd 100644
--- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt
+++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt
@@ -349,7 +349,7 @@ public class SchemeManagerImpl(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(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(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)
}
diff --git a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt
index ebd0de554a1c..12f8975480c9 100644
--- a/platform/configuration-store-impl/src/StateStorageManagerImpl.kt
+++ b/platform/configuration-store-impl/src/StateStorageManagerImpl.kt
@@ -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 = javaClass(), @SuppressWarnings("deprecation") stateSplitter: Class = javaClass()): StateStorage {
+ fun getOrCreateStorage(fileSpec: String, roamingType: RoamingType = RoamingType.DEFAULT, storageClass: Class = StateStorage::class.java, @SuppressWarnings("deprecation") stateSplitter: Class = StateSplitterEx::class.java): StateStorage {
val collapsedPath = normalizeFileSpec(fileSpec)
- val key = if (storageClass == javaClass()) 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, collapsedPath: String, roamingType: RoamingType, @SuppressWarnings("deprecation") stateSplitter: Class): StateStorage {
- if (storageClass != javaClass()) {
+ 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 != javaClass()) {
+ if (stateSplitter != StateSplitter::class.java && stateSplitter != StateSplitterEx::class.java) {
val storage = MyDirectoryStorage(this, File(filePath), ReflectionUtil.newInstance(stateSplitter))
virtualFileTracker?.put(filePath, storage)
return storage
diff --git a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt
index 3b125e60db94..7278059c44cd 100644
--- a/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt
+++ b/platform/configuration-store-impl/testSrc/ApplicationStoreTest.kt
@@ -67,7 +67,7 @@ class ApplicationStoreTest {
component.foo = "newValue"
componentStore.save(SmartList())
- assertThat(streamProvider.data.get(RoamingType.DEFAULT)!!.get("proxy.xml")).isEqualTo("\n" + " \n" + " \n" + " \n" + "")
+ assertThat(streamProvider.data.get(RoamingType.DEFAULT)!!.get("new.xml")).isEqualTo("\n" + " \n" + "")
}
@Test fun `load from stream provider`() {
@@ -75,8 +75,8 @@ class ApplicationStoreTest {
val streamProvider = MyStreamProvider()
val map = THashMap()
- val fileSpec = "proxy.xml"
- map.put(fileSpec, "\n \n \n \n")
+ val fileSpec = "new.xml"
+ map.put(fileSpec, "\n \n")
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", "")
- writeConfig("proxy.xml", "")
+ val oldFile = writeConfig("old.xml", "${createComponentData("old")}")
+ writeConfig("new.xml", "${createComponentData("new")}")
testAppConfig.refreshVfs()
@@ -109,6 +109,29 @@ class ApplicationStoreTest {
assertThat(oldFile).doesNotExist()
}
+ private fun createComponentData(foo: String) = """"""
+
+ @Test fun `remove data from deprecated storage if another component data exists`() {
+ val data = createComponentData("new")
+ val oldFile = writeConfig("old.xml", """
+
+ ${createComponentData("old")}
+ """)
+ writeConfig("new.xml", "$data")
+
+ testAppConfig.refreshVfs()
+
+ val component = SeveralStoragesConfigured()
+ componentStore.initComponent(component, false)
+ assertThat(component.foo).isEqualTo("new")
+
+ saveStore()
+
+ assertThat(oldFile).hasContent("""
+
+""")
+ }
+
@State(name = "A", storages = arrayOf(Storage(file = "a.xml")))
private open class A : PersistentStateComponent {
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())!!
+ 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 {
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 {
override fun getState() = this
diff --git a/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt
index d3b6269745ce..7d96ad1e6ba2 100644
--- a/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt
+++ b/platform/configuration-store-impl/testSrc/DefaultProjectStoreTest.kt
@@ -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 = listOf(DependencyOnPlugin("fake", "0", "1"))
+ private val requiredPlugins = listOf(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().getAllDependencies()).isEqualTo(requiredPlugins)
}
}
-}
\ No newline at end of file
+}
+
+val IComponentStore.storageManager: StateStorageManager
+ get() = getStateStorageManager()
\ No newline at end of file
diff --git a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt
index 4a6e417e69e7..6ef7d9026071 100644
--- a/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt
+++ b/platform/configuration-store-impl/testSrc/ModuleStoreTest.kt
@@ -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 {
diff --git a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt
index e3f4e94c1efe..935edfed2b4a 100644
--- a/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt
+++ b/platform/configuration-store-impl/testSrc/ProjectStoreTest.kt
@@ -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 =
"\n" +
"\n" +
@@ -81,7 +83,7 @@ class ProjectStoreTest {
" \n" +
""
- State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE)))
+ @State(name = "AATestComponent", storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE)))
private class TestComponent : PersistentStateComponent {
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)
}
}
diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
index 91c25b201d02..da842436ca58 100644
--- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
+++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt
@@ -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())!! }
+ 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("\$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("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() {
- override fun readScheme(element: Element) = XmlSerializer.deserialize(element, javaClass())
+ 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() {
fun SchemeManagerImpl<*, *>.save() {
val errors = SmartList()
save(errors)
- CompoundRuntimeException.doThrow(errors)
+ CompoundRuntimeException.throwIfNotEmpty(errors)
}
public fun T._serialize(filter: SerializationFilter? = SkipDefaultValuesSerializationFilters()): Element = XmlSerializer.serialize(this, filter)
\ No newline at end of file
diff --git a/platform/configuration-store-impl/testSrc/StoreTestSuite.kt b/platform/configuration-store-impl/testSrc/StoreTestSuite.kt
index 07759bbd03fb..e9cfdcae4c69 100644
--- a/platform/configuration-store-impl/testSrc/StoreTestSuite.kt
+++ b/platform/configuration-store-impl/testSrc/StoreTestSuite.kt
@@ -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,
diff --git a/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt b/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt
index f94298331401..7a80a34c7c3d 100644
--- a/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt
+++ b/platform/configuration-store-impl/testSrc/XmlElementStorageTest.kt
@@ -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())
+ 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())
+ val state = storage.getState(this, "test", Element::class.java)
assertThat(state).isNull()
}
diff --git a/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java b/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java
index 36299685bc51..7ae80097923f 100644
--- a/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java
+++ b/platform/core-api/src/com/intellij/psi/PsiDocumentManager.java
@@ -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.
*
diff --git a/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java b/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java
index 27a39aeec605..6c64dd0165cf 100644
--- a/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java
+++ b/platform/core-api/src/com/intellij/psi/tree/ILazyParseableElementType.java
@@ -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.
+ *
+ *
+ * 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());
diff --git a/platform/core-api/src/com/intellij/psi/util/CachedValuesManager.java b/platform/core-api/src/com/intellij/psi/util/CachedValuesManager.java
index 84064746e0b6..a5c23298b670 100644
--- a/platform/core-api/src/com/intellij/psi/util/CachedValuesManager.java
+++ b/platform/core-api/src/com/intellij/psi/util/CachedValuesManager.java
@@ -123,8 +123,13 @@ public abstract class CachedValuesManager {
* @return The cached value
*/
public static T getCachedValue(@NotNull final PsiElement psi, @NotNull final CachedValueProvider provider) {
- CachedValuesManager manager = getManager(psi.getProject());
- return manager.getCachedValue(psi, manager.getKeyForClass(provider.getClass()), new CachedValueProvider() {
+ Key> key = getKeyForClass(provider.getClass(), globalKeyForProvider);
+ CachedValue value = psi.getUserData(key);
+ if (value != null) {
+ return value.getValue();
+ }
+
+ return getManager(psi.getProject()).getCachedValue(psi, key, new CachedValueProvider() {
@Nullable
@Override
public Result compute() {
@@ -138,8 +143,15 @@ public abstract class CachedValuesManager {
}
private final ConcurrentMap> keyForProvider = ContainerUtil.newConcurrentMap();
+ private static final ConcurrentMap> globalKeyForProvider = ContainerUtil.newConcurrentMap();
+
@NotNull
public Key> getKeyForClass(@NotNull Class> providerClass) {
+ return getKeyForClass(providerClass, keyForProvider);
+ }
+
+ @NotNull
+ private static Key> getKeyForClass(@NotNull Class> providerClass, ConcurrentMap> keyForProvider) {
String name = providerClass.getName();
assert name != null : providerClass + " doesn't have a name; can't be used for cache value provider";
Key key = keyForProvider.get(name);
diff --git a/platform/core-api/src/com/intellij/util/ExecutorsQuery.java b/platform/core-api/src/com/intellij/util/ExecutorsQuery.java
index 1b4bedc24fbb..fda929cc77ab 100644
--- a/platform/core-api/src/com/intellij/util/ExecutorsQuery.java
+++ b/platform/core-api/src/com/intellij/util/ExecutorsQuery.java
@@ -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 extends AbstractQuery consumer) {
for (QueryExecutor executor : myExecutors) {
try {
+ ProgressManager.checkCanceled();
if (!executor.execute(myParameters, consumer)) {
return false;
}
diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
index d42d26f24198..b544bfef1dad 100644
--- a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java
@@ -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 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;
diff --git a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
index a37613c76fb0..9761e4882cc5 100644
--- a/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
+++ b/platform/core-impl/src/com/intellij/pom/core/impl/PomModelImpl.java
@@ -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);
}
}
}
diff --git a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
index 635754871769..e99ef0920388 100644
--- a/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
+++ b/platform/core-impl/src/com/intellij/psi/PsiAnchor.java
@@ -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) {
diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiCachedValue.java b/platform/core-impl/src/com/intellij/psi/impl/PsiCachedValue.java
index 67aef5c6c605..f9f6b0d0115a 100644
--- a/platform/core-impl/src/com/intellij/psi/impl/PsiCachedValue.java
+++ b/platform/core-impl/src/com/intellij/psi/impl/PsiCachedValue.java
@@ -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 extends CachedValueBase {
}
@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