Merge branch 'master' of git+ssh://git.labs.intellij.net/idea/community

This commit is contained in:
Sergey Ignatov
2013-12-19 12:56:44 +04:00
12 changed files with 73 additions and 45 deletions
@@ -153,54 +153,55 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
return;
}
lExpr.accept(this);
IElementType op = expression.getOperationTokenType();
PsiType type = expression.getType();
boolean isBoolean = PsiType.BOOLEAN.equals(type);
if (op == JavaTokenType.EQ) {
lExpr.accept(this);
rExpr.accept(this);
generateBoxingUnboxingInstructionFor(rExpr, type);
}
else if (op == JavaTokenType.ANDEQ) {
if (isBoolean) {
generateNonLazyExpression(true, lExpr, rExpr, type);
generateBooleanAssignmentExpression(true, lExpr, rExpr, type);
}
else {
generateDefaultBinOp(lExpr, rExpr, type);
generateDefaultAssignmentBinOp(lExpr, rExpr, type);
}
}
else if (op == JavaTokenType.OREQ) {
if (isBoolean) {
generateNonLazyExpression(false, lExpr, rExpr, type);
generateBooleanAssignmentExpression(false, lExpr, rExpr, type);
}
else {
generateDefaultBinOp(lExpr, rExpr, type);
generateDefaultAssignmentBinOp(lExpr, rExpr, type);
}
}
else if (op == JavaTokenType.XOREQ) {
if (isBoolean) {
generateXorExpression(expression, new PsiExpression[]{lExpr, rExpr}, type);
generateXorExpression(expression, new PsiExpression[]{lExpr, rExpr}, type, true);
}
else {
generateDefaultBinOp(lExpr, rExpr, type);
generateDefaultAssignmentBinOp(lExpr, rExpr, type);
}
}
else if (op == JavaTokenType.PLUSEQ && type != null && type.equalsToText(JAVA_LANG_STRING)) {
lExpr.accept(this);
addInstruction(new DupInstruction());
rExpr.accept(this);
addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject()));
}
else {
generateDefaultBinOp(lExpr, rExpr, type);
generateDefaultAssignmentBinOp(lExpr, rExpr, type);
}
addInstruction(new AssignInstruction(rExpr));
finishElement(expression);
}
private void generateDefaultBinOp(PsiExpression lExpr, PsiExpression rExpr, final PsiType exprType) {
private void generateDefaultAssignmentBinOp(PsiExpression lExpr, PsiExpression rExpr, final PsiType exprType) {
lExpr.accept(this);
addInstruction(new DupInstruction());
generateBoxingUnboxingInstructionFor(lExpr,exprType);
rExpr.accept(this);
generateBoxingUnboxingInstructionFor(rExpr, exprType);
@@ -1062,7 +1063,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
generateOrExpression(operands, type, true);
}
else if (op == JavaTokenType.XOR && PsiType.BOOLEAN.equals(type)) {
generateXorExpression(expression, operands, type);
generateXorExpression(expression, operands, type, false);
}
else if (op == JavaTokenType.AND && PsiType.BOOLEAN.equals(type)) {
generateAndExpression(operands, type, false);
@@ -1153,9 +1154,12 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
}
private void generateXorExpression(PsiExpression expression, PsiExpression[] operands, final PsiType exprType) {
private void generateXorExpression(PsiExpression expression, PsiExpression[] operands, final PsiType exprType, boolean forAssignment) {
PsiExpression operand = operands[0];
operand.accept(this);
if (forAssignment) {
addInstruction(new DupInstruction());
}
generateBoxingUnboxingInstructionFor(operand, exprType);
for (int i = 1; i < operands.length; i++) {
operand = operands[i];
@@ -1187,7 +1191,11 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
}
private void generateNonLazyExpression(boolean and, PsiExpression lExpression, PsiExpression rExpression, PsiType exprType) {
private void generateBooleanAssignmentExpression(boolean and, PsiExpression lExpression, PsiExpression rExpression, PsiType exprType) {
lExpression.accept(this);
addInstruction(new DupInstruction());
generateBoxingUnboxingInstructionFor(lExpression, exprType);
rExpression.accept(this);
generateBoxingUnboxingInstructionFor(rExpression, exprType);
@@ -1414,14 +1422,14 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
if (contracts.size() > 1) {
addInstruction(new DupInstruction(args.length, contracts.size() - 1));
}
for (MethodContract contract : contracts) {
handleContract(expression, contract);
for (int i = 0; i < contracts.size(); i++) {
handleContract(expression, contracts.get(i), contracts.size() - 1 - i);
}
pushUnknownReturnValue(expression); // goto here if all contracts are false
return true;
}
private void handleContract(PsiMethodCallExpression expression, MethodContract contract) {
private void handleContract(PsiMethodCallExpression expression, MethodContract contract, int remainingContracts) {
PsiExpression[] args = expression.getArgumentList().getExpressions();
final ControlFlow.ControlFlowOffset exitPoint = getEndOffset(expression);
@@ -1448,6 +1456,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
continueCheckingContract.setOffset(myCurrentFlow.getInstructionCount());
}
for (int j = 0; j < remainingContracts * args.length; j++) {
addInstruction(new PopInstruction());
}
// if contract is true
switch (contract.returnValue) {
case ANY_VALUE:
@@ -1,4 +1,5 @@
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
public class Foo {
@@ -6,8 +7,21 @@ public class Foo {
return escapeStr(s, escaper);
}
String foo2(Object escaper, @Nullable String s) {
return <warning descr="Expression 'escapeStr(s, escaper)' might evaluate to null but is returned by the method which is not declared as @Nullable">escapeStr(s, escaper)</warning>;
}
void foo3(@Nullable String s) {
foo2(this, escapeStr(s));
}
@Contract("null,_->null;!null,_->!null")
String escapeStr(String s, Object o) {
return s;
}
@Contract("null->null;!null->!null")
String escapeStr(String s) {
return s;
}
}
@@ -0,0 +1,12 @@
class Some {
boolean foo(Object first, Object second) {
boolean isEqual = true;
if (<error descr="Operator '||' cannot be applied to 'boolean', 'java.lang.Object'">first != null || second</error> -= null) {
return isEqual;
}
return isEqual;
}
}
@@ -301,5 +301,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testDontMakeUnrelatedVariableFalseWhenMerging() { doTest(); }
public void testDontLoseInequalityInformation() { doTest(); }
public void testNotEqualsTypo() { doTest(); }
public void _testNullCheckBeforeInstanceof() { doTest(); } // http://youtrack.jetbrains.com/issue/IDEA-113220
}
@@ -329,6 +329,10 @@ public class EditorHyperlinkSupport {
Collection<RangeHighlighter> sortedHighlighters,
final int delta,
final Consumer<RangeHighlighter> action) {
if (sortedHighlighters.isEmpty()) {
return null;
}
final List<RangeHighlighter> ranges = new ArrayList<RangeHighlighter>(sortedHighlighters);
int i;
for (i = 0; i < ranges.size(); i++) {
@@ -337,7 +341,8 @@ public class EditorHyperlinkSupport {
break;
}
}
int newIndex = i > 0 ? i % ranges.size() : 0;
i = i % ranges.size();
int newIndex = i;
while (newIndex < ranges.size() && newIndex >= 0) {
newIndex = (newIndex + delta + ranges.size()) % ranges.size();
final RangeHighlighter next = ranges.get(newIndex);
@@ -87,12 +87,7 @@ class CacheUpdateRunner {
int percent = (int)(processed.size() * 100 / total);
indicator.setText("Indexing... " + percent + "%");
if (ApplicationManager.getApplication().isInternal()) {
if (virtualFile.isValid()) {
indicator.setText2(virtualFile.getPresentableUrl());
}
else {
indicator.setText2("");
}
indicator.setText2(virtualFile.getPresentableUrl());
}
}
}
@@ -100,12 +100,7 @@ public class DirectoryGroupingRule implements UsageGroupingRule {
@NotNull
public String getText(UsageView view) {
String relativePath = VfsUtilCore.getRelativePath(myDir, myProject.getBaseDir(), File.separatorChar);
if (relativePath != null) {
return relativePath;
}
String url = myDir.getPresentableUrl();
return url != null ? url : "<invalid>";
return relativePath != null ? relativePath : myDir.getPresentableUrl();
}
@Override
@@ -79,12 +79,6 @@ public class GitUtil {
if (o2 == null) {
return 1;
}
if (o1.getPresentableUrl() == null) {
return -1;
}
if (o2.getPresentableUrl() == null) {
return 1;
}
return o1.getPresentableUrl().compareTo(o2.getPresentableUrl());
}
};
@@ -155,7 +155,7 @@ public class GitUIUtil {
return new ListCellRendererWrapper<VirtualFile>() {
@Override
public void customize(final JList list, final VirtualFile file, final int index, final boolean selected, final boolean hasFocus) {
setText(file == null || !file.isValid() ? "(invalid)" : file.getPresentableUrl());
setText(file == null ? "(invalid)" : file.getPresentableUrl());
}
};
}
@@ -58,7 +58,7 @@ public class GroovycOSProcessHandler extends BaseOSProcessHandler {
super.notifyTextAvailable(text, outputType);
if (LOG.isDebugEnabled()) {
LOG.debug("Received from groovyc: " + text);
LOG.debug("Received from groovyc " + outputType + ": " + text);
}
if (outputType == ProcessOutputTypes.SYSTEM) {
@@ -197,14 +197,17 @@ public class GroovycOSProcessHandler extends BaseOSProcessHandler {
public boolean shouldRetry() {
if (getProcess().exitValue() != 0) {
LOG.debug("Non-zero exit code");
return true;
}
for (CompilerMessage message : compilerMessages) {
if (message.getKind() == BuildMessage.Kind.ERROR) {
LOG.debug("Error message: " + message);
return true;
}
}
if (getStdErr().length() > 0) {
LOG.debug("Non-empty stderr: '" + getStdErr() + "'");
return true;
}
return false;
@@ -188,13 +188,7 @@ public class DependentGroovycRunner {
continue;
}
unit.addSource(new SourceUnit(file, unit.getConfiguration(), unit.getClassLoader(), unit.getErrorCollector()) {
public void parse() throws CompilationFailedException {
System.out.println(GroovyRtConstants.PRESENTABLE_MESSAGE + "Parsing " + file.getName() + "...");
super.parse();
System.out.println(GroovyRtConstants.CLEAR_PRESENTABLE);
}
});
unit.addSource(new SourceUnit(file, unit.getConfiguration(), unit.getClassLoader(), unit.getErrorCollector()));
}
}
@@ -297,7 +297,9 @@ public class MavenResumeAction extends AnAction {
goals.add(myResumeModuleId);
}
myRunner.execute(new ExecutionEnvironmentBuilder(myEnvironment).setContentToReuse(null).build());
runConfiguration.getRunnerParameters().setGoals(goals);
myRunner.execute(new ExecutionEnvironmentBuilder(myEnvironment).setContentToReuse(null).setRunProfile(runConfiguration).build());
}
catch (RunCanceledByUserException ignore) {
}