From ca0da0467f7a2c9ff43517a116ca60c859d362a3 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 12 Aug 2010 12:13:02 +0400 Subject: [PATCH 1/5] Git: rename detection for show diff from annotation --- .../GitCommittedChangeListProvider.java | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java b/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java index 3faed6261dc7..dd9d77760fb4 100644 --- a/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java +++ b/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.*; +import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.committed.DecoratorManager; import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper; import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary; @@ -227,7 +228,6 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider< @Override public Pair getOneList(VirtualFile file, final VcsRevisionNumber number) throws VcsException { - // todo implement in proper way final FilePathImpl filePath = new FilePathImpl(file); final GitRepositoryLocation l = (GitRepositoryLocation) getLocationFor(filePath); VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(l.getRoot()); @@ -239,6 +239,7 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider< GitUtil.getLocalCommittedChanges(myProject, root, new Consumer() { public void consume(GitSimpleHandler h) { h.addParameters("-n1"); + h.addParameters("-M"); h.addParameters(number.asString()); } }, new Consumer() { @@ -247,7 +248,45 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider< result[0] = committedChangeList; } }, false); - return new Pair(result[0], filePath); + + final Collection changes = result[0].getChanges(); + if (changes.size() == 1) { + return new Pair(result[0], changes.iterator().next().getAfterRevision().getFile()); + } + for (Change change : changes) { + if (change.getAfterRevision() != null && filePath.getIOFile().equals(change.getAfterRevision().getFile().getIOFile())) { + return new Pair(result[0], filePath); + } + } + // go for history + final File[] correctPath = new File[1]; + correctPath[0] = filePath.getIOFile(); + GitUtil.getLocalCommittedChanges(myProject, root, new Consumer() { + public void consume(GitSimpleHandler h) { + h.addParameters("-M"); + h.addParameters(number.asString() + ".."); + } + }, new Consumer() { + @Override + public void consume(CommittedChangeList committedChangeList) { + final Collection list = committedChangeList.getChanges(); + checkForRename(list, correctPath); + } + }, false); + checkForRename(result[0].getChanges(), correctPath); + return new Pair(result[0], new FilePathImpl(correctPath[0], false)); + } + + private void checkForRename(Collection list, File[] obj) { + for (Change change : list) { + if (change.getAfterRevision() != null && change.getBeforeRevision() != null) { + if (change.getAfterRevision().getFile().getIOFile().equals(obj[0]) && + (! change.getBeforeRevision().getFile().getIOFile().equals(obj[0]))) { + obj[0] = change.getBeforeRevision().getFile().getIOFile(); + return; + } + } + } } public int getFormatVersion() { From 3c34abff542201e06283e08a934a671c35327896 Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 12 Aug 2010 14:15:08 +0400 Subject: [PATCH 2/5] P4: rename detection for show diff from annotation --- .../vcs/changes/ChangesRenameContext.java | 43 +++++++++++++++++++ .../GitCommittedChangeListProvider.java | 22 +++------- 2 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesRenameContext.java diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesRenameContext.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesRenameContext.java new file mode 100644 index 000000000000..b25c44a61640 --- /dev/null +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesRenameContext.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2010 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.openapi.vcs.changes; + +import java.io.File; +import java.util.Collection; + +public class ChangesRenameContext { + private File myCurrentPath; + + public ChangesRenameContext(File currentPath) { + myCurrentPath = currentPath; + } + + public void checkForRename(final Collection list) { + for (Change change : list) { + if (change.getAfterRevision() != null && change.getBeforeRevision() != null) { + if (change.getAfterRevision().getFile().getIOFile().equals(myCurrentPath) && + (! change.getBeforeRevision().getFile().getIOFile().equals(myCurrentPath))) { + myCurrentPath = change.getBeforeRevision().getFile().getIOFile(); + return; + } + } + } + } + + public File getCurrentPath() { + return myCurrentPath; + } +} diff --git a/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java b/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java index dd9d77760fb4..7d2e980c6b92 100644 --- a/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java +++ b/plugins/git4idea/src/git4idea/changes/GitCommittedChangeListProvider.java @@ -21,6 +21,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; +import com.intellij.openapi.vcs.changes.ChangesRenameContext; import com.intellij.openapi.vcs.changes.committed.DecoratorManager; import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper; import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary; @@ -259,8 +260,7 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider< } } // go for history - final File[] correctPath = new File[1]; - correctPath[0] = filePath.getIOFile(); + final ChangesRenameContext renameContext = new ChangesRenameContext(filePath.getIOFile()); GitUtil.getLocalCommittedChanges(myProject, root, new Consumer() { public void consume(GitSimpleHandler h) { h.addParameters("-M"); @@ -270,23 +270,11 @@ public class GitCommittedChangeListProvider implements CommittedChangesProvider< @Override public void consume(CommittedChangeList committedChangeList) { final Collection list = committedChangeList.getChanges(); - checkForRename(list, correctPath); + renameContext.checkForRename(list); } }, false); - checkForRename(result[0].getChanges(), correctPath); - return new Pair(result[0], new FilePathImpl(correctPath[0], false)); - } - - private void checkForRename(Collection list, File[] obj) { - for (Change change : list) { - if (change.getAfterRevision() != null && change.getBeforeRevision() != null) { - if (change.getAfterRevision().getFile().getIOFile().equals(obj[0]) && - (! change.getBeforeRevision().getFile().getIOFile().equals(obj[0]))) { - obj[0] = change.getBeforeRevision().getFile().getIOFile(); - return; - } - } - } + renameContext.checkForRename(result[0].getChanges()); + return new Pair(result[0], new FilePathImpl(renameContext.getCurrentPath(), false)); } public int getFormatVersion() { From 016a23df7792a78ae0300b0a043910a652afc8fe Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 12 Aug 2010 14:33:11 +0400 Subject: [PATCH 3/5] New Java parser (greedy unclosed array initializers) --- .../intellij/lang/java/parser/DeclarationParser.java | 5 +++++ .../com/intellij/lang/java/parser/JavaParserUtil.java | 8 ++++++++ .../intellij/lang/java/parser/StatementParser.java | 11 ++--------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java b/java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java index b5645b47f9ca..95d2deb49f20 100644 --- a/java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java +++ b/java/java-impl/src/com/intellij/lang/java/parser/DeclarationParser.java @@ -799,6 +799,7 @@ public class DeclarationParser { parseAnnotationValue(builder); + boolean unclosed = false; while (true) { if (expect(builder, JavaTokenType.RBRACE)) { break; @@ -808,11 +809,15 @@ public class DeclarationParser { } else { error(builder, JavaErrorMessages.message("expected.rbrace")); + unclosed = true; break; } } annoArray.done(JavaElementType.ANNOTATION_ARRAY_INITIALIZER); + if (unclosed) { + annoArray.setCustomEdgeProcessors(null, GREEDY_RIGHT_EDGE_PROCESSOR); + } return annoArray; } } diff --git a/java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java b/java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java index 21e08de575e1..481eba187a22 100644 --- a/java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java +++ b/java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java @@ -27,10 +27,18 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + public class JavaParserUtil { private static final Key LANG_LEVEL_KEY = Key.create("JavaParserUtil.LanguageLevel"); + public static final WhitespacesAndCommentsProcessor GREEDY_RIGHT_EDGE_PROCESSOR = new WhitespacesAndCommentsProcessor() { + public int process(final List tokens) { + return tokens.size(); + } + }; + private JavaParserUtil() { } public static void setLanguageLevel(final PsiBuilder builder, final LanguageLevel level) { diff --git a/java/java-impl/src/com/intellij/lang/java/parser/StatementParser.java b/java/java-impl/src/com/intellij/lang/java/parser/StatementParser.java index 55334b5b0489..7d592df0e92e 100644 --- a/java/java-impl/src/com/intellij/lang/java/parser/StatementParser.java +++ b/java/java-impl/src/com/intellij/lang/java/parser/StatementParser.java @@ -17,7 +17,6 @@ package com.intellij.lang.java.parser; import com.intellij.codeInsight.daemon.JavaErrorMessages; import com.intellij.lang.PsiBuilder; -import com.intellij.lang.WhitespacesAndCommentsProcessor; import com.intellij.psi.JavaTokenType; import com.intellij.psi.impl.source.tree.ElementType; import com.intellij.psi.impl.source.tree.JavaElementType; @@ -43,12 +42,6 @@ public class StatementParser { private static final TokenSet TRY_CLOSERS_SET = TokenSet.create(JavaTokenType.CATCH_KEYWORD, JavaTokenType.FINALLY_KEYWORD); - private static final WhitespacesAndCommentsProcessor GREEDY_CODE_BLOCK_PROCESSOR = new WhitespacesAndCommentsProcessor() { - public int process(final List tokens) { - return tokens.size(); - } - }; - private StatementParser() { } @Nullable @@ -109,7 +102,7 @@ public class StatementParser { codeBlock.collapse(JavaElementType.CODE_BLOCK); if (greedyBlock) { - codeBlock.setCustomEdgeProcessors(null, GREEDY_CODE_BLOCK_PROCESSOR); + codeBlock.setCustomEdgeProcessors(null, GREEDY_RIGHT_EDGE_PROCESSOR); } return codeBlock; } @@ -127,7 +120,7 @@ public class StatementParser { codeBlock.done(JavaElementType.CODE_BLOCK); if (greedyBlock) { - codeBlock.setCustomEdgeProcessors(null, GREEDY_CODE_BLOCK_PROCESSOR); + codeBlock.setCustomEdgeProcessors(null, GREEDY_RIGHT_EDGE_PROCESSOR); } return codeBlock; } From 077c34b102c21f4e7f2c9787400879ac01a68394 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 12 Aug 2010 15:28:31 +0400 Subject: [PATCH 4/5] New Java parser (left-bound name-value pair) --- .../src/com/intellij/psi/impl/source/tree/JavaElementType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java index f3c1f5b0a5ba..0aa7f85b7b61 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java @@ -118,7 +118,7 @@ public interface JavaElementType { IElementType CATCH_SECTION = new IJavaElementType("CATCH_SECTION"); IElementType ANNOTATION_ARRAY_INITIALIZER = new IJavaElementType("ANNOTATION_ARRAY_INITIALIZER"); - IElementType NAME_VALUE_PAIR = new IJavaElementType("NAME_VALUE_PAIR"); + IElementType NAME_VALUE_PAIR = new IJavaElementType("NAME_VALUE_PAIR", true); IElementType ANNOTATION_PARAMETER_LIST = new IJavaElementType("ANNOTATION_PARAMETER_LIST", true); IElementType METHOD_RECEIVER = new IJavaElementType("METHOD_RECEIVER"); From 58379a9d76c4649b12a25ae832336938311cad38 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 12 Aug 2010 16:12:38 +0400 Subject: [PATCH 5/5] New Java parser (incomplete multi-line field declarations) --- .../lang/java/parser/JavaParserUtil.java | 2 +- ...eUnclosed.java => MultiLineUnclosed0.java} | 0 ...ineUnclosed.txt => MultiLineUnclosed0.txt} | 2 +- .../field/MultiLineUnclosed1.java | 4 + .../field/MultiLineUnclosed1.txt | 86 +++++++++++++++++++ .../declarationParsing/FieldParsingTest.java | 3 +- 6 files changed, 94 insertions(+), 3 deletions(-) rename java/java-tests/testData/psi/parser-full/declarationParsing/field/{MultiLineUnclosed.java => MultiLineUnclosed0.java} (100%) rename java/java-tests/testData/psi/parser-full/declarationParsing/field/{MultiLineUnclosed.txt => MultiLineUnclosed0.txt} (96%) create mode 100644 java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.java create mode 100644 java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.txt diff --git a/java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java b/java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java index 481eba187a22..69c41c98ddba 100644 --- a/java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java +++ b/java/java-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java @@ -132,7 +132,7 @@ public class JavaParserUtil { @Override public boolean eof() { - return getCurrentOffset() < stopAt || super.eof(); + return getCurrentOffset() >= stopAt || super.eof(); } }; } diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed.java b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed0.java similarity index 100% rename from java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed.java rename to java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed0.java diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed.txt b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed0.txt similarity index 96% rename from java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed.txt rename to java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed0.txt index da7394d7c95d..d9a11287da0e 100644 --- a/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed.txt +++ b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed0.txt @@ -1,4 +1,4 @@ -PsiJavaFile:MultiLineUnclosed.java +PsiJavaFile:MultiLineUnclosed0.java PsiImportList PsiClass:Test diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.java b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.java new file mode 100644 index 000000000000..4841f75dc3cb --- /dev/null +++ b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.java @@ -0,0 +1,4 @@ +class C { + String uiTest1 = new String("Test1"), + uiTest2 = new String("Test2"); +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.txt b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.txt new file mode 100644 index 000000000000..ffe4704123f4 --- /dev/null +++ b/java/java-tests/testData/psi/parser-full/declarationParsing/field/MultiLineUnclosed1.txt @@ -0,0 +1,86 @@ +PsiJavaFile:MultiLineUnclosed1.java + PsiImportList + + PsiClass:C + PsiModifierList: + + PsiKeyword:class('class') + PsiWhiteSpace(' ') + PsiIdentifier:C('C') + PsiTypeParameterList + + PsiReferenceList + + PsiReferenceList + + PsiWhiteSpace(' ') + PsiJavaToken:LBRACE('{') + PsiWhiteSpace('\n ') + PsiField:uiTest1 + PsiModifierList: + + PsiTypeElement:String + PsiJavaCodeReferenceElement:String + PsiIdentifier:String('String') + PsiReferenceParameterList + + PsiWhiteSpace(' ') + PsiIdentifier:uiTest1('uiTest1') + PsiWhiteSpace(' ') + PsiJavaToken:EQ('=') + PsiWhiteSpace(' ') + PsiNewExpression:new String("Test1") + PsiKeyword:new('new') + PsiReferenceParameterList + + PsiWhiteSpace(' ') + PsiJavaCodeReferenceElement:String + PsiIdentifier:String('String') + PsiReferenceParameterList + + PsiExpressionList + PsiJavaToken:LPARENTH('(') + PsiLiteralExpression:"Test1" + PsiJavaToken:STRING_LITERAL('"Test1"') + PsiJavaToken:RPARENTH(')') + PsiJavaToken:COMMA(',') + PsiErrorElement:Identifier expected + + PsiWhiteSpace('\n ') + PsiModifierList: + + PsiTypeElement:uiTest2 + PsiJavaCodeReferenceElement:uiTest2 + PsiIdentifier:uiTest2('uiTest2') + PsiReferenceParameterList + PsiJavaToken:LT('<') + PsiTypeElement:caret + PsiJavaCodeReferenceElement:caret + PsiIdentifier:caret('caret') + PsiReferenceParameterList + + PsiJavaToken:GT('>') + PsiErrorElement:Identifier expected + + PsiWhiteSpace(' ') + PsiErrorElement:Unexpected token + PsiJavaToken:EQ('=') + PsiWhiteSpace(' ') + PsiKeyword:new('new') + PsiWhiteSpace(' ') + PsiMethod:String + PsiModifierList: + + PsiTypeParameterList + + PsiIdentifier:String('String') + PsiParameterList:("Test2") + PsiJavaToken:LPARENTH('(') + PsiErrorElement:Parameter expected + PsiJavaToken:STRING_LITERAL('"Test2"') + PsiJavaToken:RPARENTH(')') + PsiReferenceList + + PsiJavaToken:SEMICOLON(';') + PsiWhiteSpace('\n') + PsiJavaToken:RBRACE('}') \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/lang/java/parser/declarationParsing/FieldParsingTest.java b/java/java-tests/testSrc/com/intellij/lang/java/parser/declarationParsing/FieldParsingTest.java index 938467bf6184..15f8dfb1ed4d 100644 --- a/java/java-tests/testSrc/com/intellij/lang/java/parser/declarationParsing/FieldParsingTest.java +++ b/java/java-tests/testSrc/com/intellij/lang/java/parser/declarationParsing/FieldParsingTest.java @@ -18,7 +18,8 @@ public class FieldParsingTest extends JavaParsingTestCase { public void testUnclosedSemicolon() { doTest(true); } public void testMissingInitializerExpression() { doTest(true); } - public void testMultiLineUnclosed() { doTest(true); } + public void testMultiLineUnclosed0() { doTest(true); } + public void testMultiLineUnclosed1() { doTest(true); } public void testComplexInitializer() { doTest(true); } } \ No newline at end of file