mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-02 00:57:59 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -193,14 +193,14 @@ public class AllClassesGetter {
|
||||
|
||||
|
||||
private static String getPackagePrefix(final PsiElement context, final int offset) {
|
||||
final String fileText = context.getContainingFile().getText();
|
||||
final CharSequence fileText = context.getContainingFile().getViewProvider().getContents();
|
||||
int i = offset - 1;
|
||||
while (i >= 0) {
|
||||
final char c = fileText.charAt(i);
|
||||
if (!Character.isJavaIdentifierPart(c) && c != '.') break;
|
||||
i--;
|
||||
}
|
||||
String prefix = fileText.substring(i + 1, offset);
|
||||
String prefix = fileText.subSequence(i + 1, offset).toString();
|
||||
final int j = prefix.lastIndexOf('.');
|
||||
return j > 0 ? prefix.substring(0, j) : "";
|
||||
}
|
||||
|
||||
+2
-1
@@ -49,13 +49,14 @@ import java.util.regex.Pattern;
|
||||
public class FileHeaderChecker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defaultFileTemplateUsage.FileHeaderChecker");
|
||||
|
||||
// abcdfghdjsjd kfkdjekr dfhakdjfk dkfkjgk dfjgjfkg ekfk fkgkvv ggkk eefkgjkdd jfkkkssl dfghgk gkhller hhksl lfflgl
|
||||
static ProblemDescriptor checkFileHeader(@NotNull final PsiFile file, final InspectionManager manager, boolean onTheFly) {
|
||||
TIntObjectHashMap<String> offsetToProperty = new TIntObjectHashMap<String>();
|
||||
Pattern pattern = getTemplatePattern(FileTemplateManager.getInstance()
|
||||
.getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME),
|
||||
file.getProject(), offsetToProperty
|
||||
);
|
||||
Matcher matcher = pattern.matcher(file.getText());
|
||||
Matcher matcher = pattern.matcher(file.getViewProvider().getContents());
|
||||
if (matcher.matches()) {
|
||||
final int startOffset = matcher.start(1);
|
||||
final int endOffset = matcher.end(1);
|
||||
|
||||
+1
-1
@@ -150,7 +150,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
}
|
||||
|
||||
public static boolean hasErrorElementsNearby(final PsiFile file, int startOffset, int endOffset) {
|
||||
endOffset = CharArrayUtil.shiftForward(file.getText(), endOffset, " \t\n");
|
||||
endOffset = CharArrayUtil.shiftForward(file.getViewProvider().getContents(), endOffset, " \t\n");
|
||||
for (PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffset, endOffset)) {
|
||||
if (element instanceof PsiErrorElement) {
|
||||
return true;
|
||||
|
||||
@@ -43,16 +43,21 @@ public class ClassFileViewProvider extends SingleRootFileViewProvider {
|
||||
}
|
||||
|
||||
// skip inners & anonymous
|
||||
if (isInnerClass(vFile)) return null;
|
||||
|
||||
return new ClsFileImpl(PsiManager.getInstance(project), this);
|
||||
}
|
||||
|
||||
public static boolean isInnerClass(VirtualFile vFile) {
|
||||
String name = vFile.getNameWithoutExtension();
|
||||
int index = name.lastIndexOf('$', name.length());
|
||||
if (index > 0 && index < name.length() - 1) {
|
||||
String supposedParentName = name.substring(0, index) + ".class";
|
||||
if (vFile.getParent().findChild(supposedParentName) != null) {
|
||||
return null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return new ClsFileImpl(PsiManager.getInstance(project), this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.ClassFileViewProvider;
|
||||
import com.intellij.psi.impl.source.JavaFileElementType;
|
||||
import com.intellij.psi.stubs.BinaryFileStubBuilder;
|
||||
import com.intellij.psi.stubs.PsiFileStub;
|
||||
@@ -39,7 +40,7 @@ public class ClassFileStubBuilder implements BinaryFileStubBuilder {
|
||||
|
||||
@Override
|
||||
public boolean acceptsFile(final VirtualFile file) {
|
||||
return true;
|
||||
return !ClassFileViewProvider.isInnerClass(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -489,8 +489,8 @@ public class DirectoryIndexTest extends IdeaTestCase {
|
||||
checkInfoNull(module2TestOutput);
|
||||
|
||||
assertFalse(myIndex.isProjectExcludeRoot(excluded));
|
||||
assertTrue(myIndex.isProjectExcludeRoot(projectOutput));
|
||||
assertTrue(myIndex.isProjectExcludeRoot(module2Output));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(projectOutput));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(module2Output));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput));
|
||||
|
||||
excluded.delete(this);
|
||||
@@ -508,12 +508,10 @@ public class DirectoryIndexTest extends IdeaTestCase {
|
||||
|
||||
String fileName = e.getFileName();
|
||||
if (fileName.equals("projectOutput")) {
|
||||
//todo fix and uncomment
|
||||
// assertTrue(myIndex.isProjectExcludeRoot(file));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(file));
|
||||
}
|
||||
if (fileName.equals("module2Output")) {
|
||||
//todo fix and uncomment
|
||||
// assertTrue(myIndex.isProjectExcludeRoot(file));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(file));
|
||||
}
|
||||
if (fileName.equals("module2TestOutput")) {
|
||||
assertFalse(myIndex.isProjectExcludeRoot(file));
|
||||
@@ -526,10 +524,10 @@ public class DirectoryIndexTest extends IdeaTestCase {
|
||||
assertFalse(myIndex.isProjectExcludeRoot(excluded));
|
||||
|
||||
projectOutput = myModule1Dir.createChildDirectory(this, projectOutput.getName());
|
||||
assertTrue(myIndex.isProjectExcludeRoot(projectOutput));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(projectOutput));
|
||||
|
||||
module2Output = myModule1Dir.createChildDirectory(this, module2Output.getName());
|
||||
assertTrue(myIndex.isProjectExcludeRoot(module2Output));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(module2Output));
|
||||
|
||||
module2TestOutput = myModule2Dir.createChildDirectory(this, module2TestOutput.getName());
|
||||
assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput));
|
||||
@@ -542,8 +540,8 @@ public class DirectoryIndexTest extends IdeaTestCase {
|
||||
assertEquals(created.toString(), 4, created.size());
|
||||
|
||||
assertFalse(myIndex.isProjectExcludeRoot(excluded));
|
||||
assertTrue(myIndex.isProjectExcludeRoot(projectOutput));
|
||||
assertTrue(myIndex.isProjectExcludeRoot(module2Output));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(projectOutput));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(module2Output));
|
||||
assertFalse(myIndex.isProjectExcludeRoot(module2TestOutput));
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public class CharTableImpl implements CharTable {
|
||||
|
||||
@NotNull
|
||||
public CharSequence doIntern(@NotNull CharSequence text) {
|
||||
CharSequence interned = getStaticInterned(text.toString());
|
||||
CharSequence interned = getStaticInterned(text);
|
||||
if (interned != null) {
|
||||
return interned;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public class CharTableImpl implements CharTable {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CharSequence getStaticInterned(@NotNull String text) {
|
||||
public static CharSequence getStaticInterned(@NotNull CharSequence text) {
|
||||
return STATIC_ENTRIES.get(text);
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -145,8 +145,9 @@ class CompletionAssertions {
|
||||
}
|
||||
|
||||
final TextRange range = insertedElement.getTextRange();
|
||||
String fileCopyText = fileCopy.getText();
|
||||
if ((range.getEndOffset() > fileCopyText.length()) || !range.substring(fileCopyText).equals(insertedElement.getText())) {
|
||||
CharSequence fileCopyText = fileCopy.getViewProvider().getContents();
|
||||
if ((range.getEndOffset() > fileCopyText.length()) ||
|
||||
!fileCopyText.subSequence(range.getStartOffset(), range.getEndOffset()).toString().equals(insertedElement.getText())) {
|
||||
throw new LogEventException("Inconsistent completion tree", "range=" + range + "\n" + DebugUtil.currentStackTrace(),
|
||||
createFileTextAttachment(fileCopy, originalFile), createAstAttachment(fileCopy, originalFile),
|
||||
new Attachment("Element at caret.txt", insertedElement.getText()));
|
||||
|
||||
+8
-8
@@ -84,7 +84,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
@NotNull final CompletionContributor contributor) {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset());
|
||||
final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset());
|
||||
final int lengthOfTextBeforePosition = parameters.getOffset();
|
||||
ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
if (!(indicator instanceof CompletionProgressIndicator)) {
|
||||
throw new AssertionError("createResultSet may be invoked only from completion thread: " + indicator + "!=" + getCurrentCompletion() + "; phase set at " + ourPhaseTrace);
|
||||
@@ -92,7 +92,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
CompletionProgressIndicator process = (CompletionProgressIndicator)indicator;
|
||||
CamelHumpMatcher matcher = new CamelHumpMatcher(prefix);
|
||||
CompletionSorterImpl sorter = defaultSorter(parameters, matcher);
|
||||
return new CompletionResultSetImpl(consumer, textBeforePosition, matcher, contributor,parameters, sorter, process, null);
|
||||
return new CompletionResultSetImpl(consumer, lengthOfTextBeforePosition, matcher, contributor,parameters, sorter, process, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,13 +105,13 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
}
|
||||
|
||||
private static class CompletionResultSetImpl extends CompletionResultSet {
|
||||
private final String myTextBeforePosition;
|
||||
private final int myLengthOfTextBeforePosition;
|
||||
private final CompletionParameters myParameters;
|
||||
private final CompletionSorterImpl mySorter;
|
||||
private final CompletionProgressIndicator myProcess;
|
||||
@Nullable private final CompletionResultSetImpl myOriginal;
|
||||
|
||||
public CompletionResultSetImpl(final Consumer<CompletionResult> consumer, final String textBeforePosition,
|
||||
public CompletionResultSetImpl(final Consumer<CompletionResult> consumer, final int lengthOfTextBeforePosition,
|
||||
final PrefixMatcher prefixMatcher,
|
||||
CompletionContributor contributor,
|
||||
CompletionParameters parameters,
|
||||
@@ -119,7 +119,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
@NotNull CompletionProgressIndicator process,
|
||||
@Nullable CompletionResultSetImpl original) {
|
||||
super(prefixMatcher, consumer, contributor);
|
||||
myTextBeforePosition = textBeforePosition;
|
||||
myLengthOfTextBeforePosition = lengthOfTextBeforePosition;
|
||||
myParameters = parameters;
|
||||
mySorter = sorter;
|
||||
myProcess = process;
|
||||
@@ -142,7 +142,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
@Override
|
||||
@NotNull
|
||||
public CompletionResultSet withPrefixMatcher(@NotNull final PrefixMatcher matcher) {
|
||||
return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this);
|
||||
return new CompletionResultSetImpl(getConsumer(), myLengthOfTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,7 +165,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
@NotNull
|
||||
@Override
|
||||
public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) {
|
||||
return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this);
|
||||
return new CompletionResultSetImpl(getConsumer(), myLengthOfTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,7 +183,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
public void restartCompletionOnPrefixChange(ElementPattern<String> prefixCondition) {
|
||||
final CompletionProgressIndicator indicator = getCompletionService().getCurrentCompletion();
|
||||
if (indicator != null) {
|
||||
indicator.addWatchedPrefix(myTextBeforePosition.length() - getPrefixMatcher().getPrefix().length(), prefixCondition);
|
||||
indicator.addWatchedPrefix(myLengthOfTextBeforePosition - getPrefixMatcher().getPrefix().length(), prefixCondition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -109,7 +109,9 @@ public class ProjectJdkTableImpl extends ProjectJdkTable implements PersistentSt
|
||||
@Override
|
||||
@Nullable
|
||||
public Sdk findJdk(String name) {
|
||||
for (Sdk jdk : mySdks) {
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0, len = mySdks.size(); i < len; ++i) { // avoid foreach, it instantiates ArrayList$Itr, this traversal happens very often
|
||||
final Sdk jdk = mySdks.get(i);
|
||||
if (Comparing.strEqual(name, jdk.getName())) {
|
||||
return jdk;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.openapi.fileChooser.FileTextField;
|
||||
import com.intellij.openapi.ui.ComboBoxWithWidePopup;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentListener;
|
||||
@@ -25,7 +25,7 @@ import java.awt.event.KeyListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TextFieldWithHistory extends ComboBoxWithWidePopup {
|
||||
public class TextFieldWithHistory extends ComboBox {
|
||||
private int myHistorySize = 5;
|
||||
private final MyModel myModel;
|
||||
|
||||
|
||||
+2
-1
@@ -148,7 +148,8 @@ public class ComplementaryFontsRegistry {
|
||||
boolean tryDefaultFont = true;
|
||||
List<String> fontFamilies = preferences.getEffectiveFontFamilies();
|
||||
FontInfo result;
|
||||
for (String fontFamily : fontFamilies) {
|
||||
for (int i = 0, len = fontFamilies.size(); i < len; ++i) {
|
||||
final String fontFamily = fontFamilies.get(i);
|
||||
result = doGetFontAbleToDisplay(c, preferences.getSize(fontFamily), style, fontFamily);
|
||||
if (result != null) {
|
||||
return result;
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.editor.ex.*;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.editor.markup.*;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -86,14 +87,14 @@ public final class IterationState {
|
||||
private int myEndOffset;
|
||||
private final int myEnd;
|
||||
|
||||
private final int mySelectionStart;
|
||||
private final int[] mySelectionStarts;
|
||||
private final int[] mySelectionEnds;
|
||||
private int myCurrentSelectionIndex = 0;
|
||||
|
||||
private final int mySelectionEnd;
|
||||
private final List<RangeHighlighterEx> myCurrentHighlighters = new ArrayList<RangeHighlighterEx>();
|
||||
|
||||
private final FoldingModelEx myFoldingModel;
|
||||
|
||||
private final boolean hasSelection;
|
||||
private FoldRegion myCurrentFold = null;
|
||||
private final TextAttributes myFoldTextAttributes;
|
||||
private final TextAttributes mySelectionAttributes;
|
||||
@@ -121,9 +122,9 @@ public final class IterationState {
|
||||
LOG.assertTrue(myStartOffset <= myEnd);
|
||||
myHighlighterIterator = editor.getHighlighter().createIterator(start);
|
||||
|
||||
hasSelection = useCaretAndSelection && editor.getSelectionModel().hasSelection();
|
||||
mySelectionStart = hasSelection ? editor.getSelectionModel().getSelectionStart() : -1;
|
||||
mySelectionEnd = hasSelection ? editor.getSelectionModel().getSelectionEnd() : -1;
|
||||
boolean hasSelection = useCaretAndSelection && (editor.getSelectionModel().hasSelection() || editor.getSelectionModel().hasBlockSelection());
|
||||
mySelectionStarts = hasSelection ? editor.getSelectionModel().getBlockSelectionStarts() : ArrayUtilRt.EMPTY_INT_ARRAY;
|
||||
mySelectionEnds = hasSelection ? editor.getSelectionModel().getBlockSelectionEnds() : ArrayUtilRt.EMPTY_INT_ARRAY;
|
||||
|
||||
myFoldingModel = editor.getFoldingModel();
|
||||
myFoldTextAttributes = myFoldingModel.getPlaceholderAttributes();
|
||||
@@ -235,13 +236,14 @@ public final class IterationState {
|
||||
public void advance() {
|
||||
myStartOffset = myEndOffset;
|
||||
advanceSegmentHighlighters();
|
||||
advanceCurrentSelectionIndex();
|
||||
|
||||
myCurrentFold = myFoldingModel.fetchOutermost(myStartOffset);
|
||||
if (myCurrentFold != null) {
|
||||
myEndOffset = myCurrentFold.getEndOffset();
|
||||
}
|
||||
else {
|
||||
myEndOffset = Math.min(getHighlighterEnd(myStartOffset), getSelectionEnd(myStartOffset));
|
||||
myEndOffset = Math.min(getHighlighterEnd(myStartOffset), getSelectionEnd());
|
||||
myEndOffset = Math.min(myEndOffset, getMinSegmentHighlightersEnd());
|
||||
myEndOffset = Math.min(myEndOffset, getFoldRangesEnd(myStartOffset));
|
||||
myEndOffset = Math.min(myEndOffset, getCaretEnd(myStartOffset));
|
||||
@@ -290,17 +292,26 @@ public final class IterationState {
|
||||
return min;
|
||||
}
|
||||
|
||||
private int getSelectionEnd(int start) {
|
||||
if (!hasSelection) {
|
||||
private void advanceCurrentSelectionIndex() {
|
||||
while (myCurrentSelectionIndex < mySelectionEnds.length && myStartOffset >= mySelectionEnds[myCurrentSelectionIndex]) {
|
||||
myCurrentSelectionIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
private int getSelectionEnd() {
|
||||
if (myCurrentSelectionIndex >= mySelectionStarts.length) {
|
||||
return myEnd;
|
||||
}
|
||||
if (mySelectionStart > start) {
|
||||
return mySelectionStart;
|
||||
if (myStartOffset < mySelectionStarts[myCurrentSelectionIndex]) {
|
||||
return mySelectionStarts[myCurrentSelectionIndex];
|
||||
}
|
||||
if (mySelectionEnd > start) {
|
||||
return mySelectionEnd;
|
||||
else {
|
||||
return mySelectionEnds[myCurrentSelectionIndex];
|
||||
}
|
||||
return myEnd;
|
||||
}
|
||||
|
||||
private boolean isInSelection() {
|
||||
return myCurrentSelectionIndex < mySelectionStarts.length && myStartOffset >= mySelectionStarts[myCurrentSelectionIndex];
|
||||
}
|
||||
|
||||
private void advanceSegmentHighlighters() {
|
||||
@@ -362,7 +373,7 @@ public final class IterationState {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isInSelection = hasSelection && myStartOffset >= mySelectionStart && myStartOffset < mySelectionEnd;
|
||||
boolean isInSelection = isInSelection();
|
||||
boolean isInCaretRow = myStartOffset >= myCaretRowStart && myStartOffset < myCaretRowEnd;
|
||||
boolean isInGuardedBlock = myDocument.getOffsetGuard(myStartOffset) != null;
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ dump.threads.on.empty.lookup.description=Whether IDEA should issue a thread dump
|
||||
|
||||
file.structure.tree.mode=true
|
||||
|
||||
directory.index.use.root.index=false
|
||||
directory.index.use.root.index=true
|
||||
directory.index.use.root.index.description=Requires restart
|
||||
directory.index.compare.implementations=false
|
||||
directory.index.compare.implementations.description=Will make the IDE slow. Requires restart
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.editor.impl;
|
||||
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class IterationStateTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
|
||||
public void testBlockSelection() {
|
||||
verifySplitting("aa,<block>bb\ncc,d</block>d",
|
||||
new Segment(0, 3, Color.BLACK),
|
||||
new Segment(3, 4, Color.WHITE),
|
||||
new Segment(4, 5, Color.BLACK),
|
||||
new Segment(5, 6, Color.BLACK),
|
||||
new Segment(6, 9, Color.BLACK),
|
||||
new Segment(9, 10, Color.WHITE),
|
||||
new Segment(10, 11, Color.BLACK));
|
||||
}
|
||||
|
||||
private void verifySplitting(String text, Segment... expectedSegments) {
|
||||
myFixture.configureByText(PlainTextFileType.INSTANCE, text);
|
||||
EditorEx editor = (EditorEx)myFixture.getEditor();
|
||||
IterationState iterationState = new IterationState(editor, 0, editor.getDocument().getTextLength(), true);
|
||||
try {
|
||||
List<Segment> actualSegments = new ArrayList<Segment>();
|
||||
do {
|
||||
actualSegments.add(new Segment(iterationState.getStartOffset(),
|
||||
iterationState.getEndOffset(),
|
||||
iterationState.getMergedAttributes().getForegroundColor()));
|
||||
iterationState.advance();
|
||||
}
|
||||
while (!iterationState.atEnd());
|
||||
|
||||
Assert.assertArrayEquals(expectedSegments, actualSegments.toArray());
|
||||
}
|
||||
finally {
|
||||
iterationState.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Segment {
|
||||
private final int start;
|
||||
private final int end;
|
||||
private final Color fgColor;
|
||||
|
||||
private Segment(int start, int end, @NotNull Color fgColor) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.fgColor = fgColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Segment segment = (Segment)o;
|
||||
|
||||
if (end != segment.end) return false;
|
||||
if (start != segment.start) return false;
|
||||
if (!fgColor.equals(segment.fgColor)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = start;
|
||||
result = 31 * result + end;
|
||||
result = 31 * result + fgColor.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Segment{" +
|
||||
"start=" + start +
|
||||
", end=" + end +
|
||||
", color=" + fgColor +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,6 @@ public class VcsLogUI {
|
||||
public void run() {
|
||||
myMainFrame.getGraphTable().setPreferredColumnWidths();
|
||||
myMainFrame.getGraphTable().repaint();
|
||||
myMainFrame.refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.intellij.vcs.log.ui.frame;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -75,6 +76,14 @@ public class BranchesPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Project project = dataHolder.getProject();
|
||||
project.getMessageBus().connect(project).subscribe(VcsLogDataHolder.REFRESH_COMPLETED, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
rebuild();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -199,10 +199,6 @@ public class MainFrame extends JPanel implements TypeSafeDataProvider {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
myBranchesPanel.rebuild();
|
||||
}
|
||||
|
||||
public void setBranchesPanelVisible(boolean visible) {
|
||||
myBranchesPanel.setVisible(visible);
|
||||
}
|
||||
|
||||
@@ -51,16 +51,16 @@ public class GraphCommitCellRender extends AbstractPaddingCellRender {
|
||||
@Override
|
||||
protected int getLeftPadding(JTable table, @Nullable Object value) {
|
||||
GraphCommitCell cell = (GraphCommitCell)value;
|
||||
|
||||
if (cell == null) {
|
||||
return 0;
|
||||
}
|
||||
return calcPaddingBeforeText(cell, (Graphics2D)table.getGraphics());
|
||||
}
|
||||
|
||||
int refPadding = calcRefsPadding(cell.getRefsToThisCommit(), (Graphics2D)table.getGraphics());
|
||||
|
||||
private int calcPaddingBeforeText(GraphCommitCell cell, Graphics2D g) {
|
||||
int refPadding = calcRefsPadding(cell.getRefsToThisCommit(), g);
|
||||
int countCells = cell.getPrintCell().countCell();
|
||||
int graphPadding = countCells * WIDTH_NODE;
|
||||
|
||||
return refPadding + graphPadding;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,8 @@ public class GraphCommitCellRender extends AbstractPaddingCellRender {
|
||||
return;
|
||||
}
|
||||
|
||||
BufferedImage image = UIUtil.createImage(1000, HEIGHT_CELL, BufferedImage.TYPE_INT_ARGB);
|
||||
int width = calcPaddingBeforeText(cell, (Graphics2D)g);
|
||||
BufferedImage image = UIUtil.createImage(width, HEIGHT_CELL, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2 = image.createGraphics();
|
||||
g2.setBackground(new Color(0, 0, 0, 0));
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ package git4idea.log;
|
||||
import com.intellij.dvcs.repo.RepositoryManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.vcs.log.RefGroup;
|
||||
@@ -12,14 +14,11 @@ import com.intellij.vcs.log.VcsRef;
|
||||
import com.intellij.vcs.log.VcsRefType;
|
||||
import com.intellij.vcs.log.impl.SingletonRefGroup;
|
||||
import git4idea.GitBranch;
|
||||
import git4idea.GitLocalBranch;
|
||||
import git4idea.GitRemoteBranch;
|
||||
import git4idea.branch.GitBranchesCollection;
|
||||
import git4idea.repo.GitBranchTrackInfo;
|
||||
import git4idea.repo.GitRemote;
|
||||
import git4idea.repo.GitRepository;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
@@ -136,36 +135,39 @@ public class GitRefManager implements VcsLogRefManager {
|
||||
List<VcsRef> trackedBranches = ContainerUtil.newArrayList();
|
||||
MultiMap<GitRemote, VcsRef> remoteRefGroups = MultiMap.create();
|
||||
|
||||
for (VcsRef ref : refs) {
|
||||
if (ref.getType() == HEAD) {
|
||||
simpleGroups.add(new SingletonRefGroup(ref));
|
||||
MultiMap<VirtualFile, VcsRef> refsByRoot = groupRefsByRoot(refs);
|
||||
for (Map.Entry<VirtualFile, Collection<VcsRef>> entry : refsByRoot.entrySet()) {
|
||||
VirtualFile root = entry.getKey();
|
||||
Collection<VcsRef> refsInRoot = entry.getValue();
|
||||
|
||||
GitRepository repository = myRepositoryManager.getRepositoryForRoot(root);
|
||||
if (repository == null) {
|
||||
LOG.warn("No repository for root: " + root);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
GitRepository repository = myRepositoryManager.getRepositoryForRoot(ref.getRoot());
|
||||
if (repository == null) {
|
||||
LOG.warn("No repository for root: " + ref.getRoot());
|
||||
|
||||
Set<String> locals = getLocalBranches(repository);
|
||||
Set<String> tracked = getTrackedRemoteBranches(repository);
|
||||
Map<String, GitRemote> nonTracked = getNonTrackedRemoteBranches(repository);
|
||||
|
||||
for (VcsRef ref : refsInRoot) {
|
||||
if (ref.getType() == HEAD) {
|
||||
simpleGroups.add(new SingletonRefGroup(ref));
|
||||
continue;
|
||||
}
|
||||
Collection<GitBranchTrackInfo> trackInfos = repository.getBranchTrackInfos();
|
||||
GitBranchesCollection branches = repository.getBranches();
|
||||
|
||||
GitLocalBranch localBranch = findBranchByName(ref, branches.getLocalBranches());
|
||||
if (localBranch != null) {
|
||||
String refName = ref.getName();
|
||||
if (locals.contains(refName)) {
|
||||
localBranches.add(ref);
|
||||
}
|
||||
else if (tracked.contains(refName)) {
|
||||
trackedBranches.add(ref);
|
||||
}
|
||||
else if (nonTracked.containsKey(refName)) {
|
||||
remoteRefGroups.putValue(nonTracked.get(refName), ref);
|
||||
}
|
||||
else {
|
||||
GitRemoteBranch remoteBranch = findBranchByName(ref, branches.getRemoteBranches());
|
||||
if (remoteBranch != null) {
|
||||
if (isTracked(trackInfos, remoteBranch)) {
|
||||
trackedBranches.add(ref);
|
||||
}
|
||||
else {
|
||||
remoteRefGroups.putValue(remoteBranch.getRemote(), ref);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.warn("Didn't find ref neither in local nor in remote branches: " + ref);
|
||||
}
|
||||
LOG.warn("Didn't find ref neither in local nor in remote branches: " + ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,23 +184,57 @@ public class GitRefManager implements VcsLogRefManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <T extends GitBranch> T findBranchByName(final VcsRef ref, Collection<T> branches) {
|
||||
return ContainerUtil.find(branches, new Condition<T>() {
|
||||
private static Set<String> getLocalBranches(GitRepository repository) {
|
||||
return ContainerUtil.map2Set(repository.getBranches().getLocalBranches(), new Function<GitBranch, String>() {
|
||||
@Override
|
||||
public boolean value(T branch) {
|
||||
return branch.getName().equals(ref.getName());
|
||||
public String fun(GitBranch branch) {
|
||||
return branch.getName();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isTracked(Collection<GitBranchTrackInfo> trackInfos, final GitRemoteBranch remoteBranch) {
|
||||
return ContainerUtil.find(trackInfos, new Condition<GitBranchTrackInfo>() {
|
||||
@Override
|
||||
public boolean value(GitBranchTrackInfo info) {
|
||||
return info.getRemoteBranch().equals(remoteBranch);
|
||||
@NotNull
|
||||
private static Set<String> getTrackedRemoteBranches(@NotNull GitRepository repository) {
|
||||
Set<GitRemoteBranch> all = new HashSet<GitRemoteBranch>(repository.getBranches().getRemoteBranches());
|
||||
Set<String> tracked = new HashSet<String>();
|
||||
for (GitBranchTrackInfo info : repository.getBranchTrackInfos()) {
|
||||
GitRemoteBranch trackedRemoteBranch = info.getRemoteBranch();
|
||||
if (all.contains(trackedRemoteBranch)) { // check that this branch really exists, not just written in .git/config
|
||||
tracked.add(trackedRemoteBranch.getName());
|
||||
}
|
||||
}) != null;
|
||||
}
|
||||
return tracked;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, GitRemote> getNonTrackedRemoteBranches(@NotNull GitRepository repository) {
|
||||
Set<GitRemoteBranch> all = new HashSet<GitRemoteBranch>(repository.getBranches().getRemoteBranches());
|
||||
Set<String> tracked = getTrackedRemoteBranchesFromConfig(repository);
|
||||
Map<String, GitRemote> nonTracked = ContainerUtil.newHashMap();
|
||||
for (GitRemoteBranch remoteBranch : all) {
|
||||
if (!tracked.contains(remoteBranch.getName())) {
|
||||
nonTracked.put(remoteBranch.getName(), remoteBranch.getRemote());
|
||||
}
|
||||
}
|
||||
return nonTracked;
|
||||
}
|
||||
|
||||
private static Set<String> getTrackedRemoteBranchesFromConfig(GitRepository repository) {
|
||||
return ContainerUtil.map2Set(repository.getBranchTrackInfos(), new Function<GitBranchTrackInfo, String>() {
|
||||
@Override
|
||||
public String fun(GitBranchTrackInfo trackInfo) {
|
||||
return trackInfo.getRemoteBranch().getName();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static MultiMap<VirtualFile, VcsRef> groupRefsByRoot(@NotNull Iterable<VcsRef> refs) {
|
||||
MultiMap<VirtualFile, VcsRef> grouped = MultiMap.create();
|
||||
for (VcsRef ref : refs) {
|
||||
grouped.putValue(ref.getRoot(), ref);
|
||||
}
|
||||
return grouped;
|
||||
}
|
||||
|
||||
private static class SimpleRefType implements VcsRefType {
|
||||
|
||||
+1
-24
@@ -37,7 +37,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEn
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.GrVariableDeclarationImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrBlockImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrClosableBlockImpl;
|
||||
@@ -308,29 +307,7 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy
|
||||
GroovyElementType ANNOTATION_ARGUMENTS = new GroovyElementType("annotation arguments");
|
||||
GroovyElementType ANNOTATION_MEMBER_VALUE_PAIR = new GroovyElementType("annotation member value pair");
|
||||
|
||||
GrStubElementType<GrAnnotationStub, GrAnnotation> ANNOTATION = new GrStubElementType<GrAnnotationStub, GrAnnotation>("annotation") {
|
||||
|
||||
@Override
|
||||
public GrAnnotation createPsi(@NotNull GrAnnotationStub stub) {
|
||||
return new GrAnnotationImpl(stub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrAnnotationStub createStub(@NotNull GrAnnotation psi, StubElement parentStub) {
|
||||
return new GrAnnotationStub(parentStub, psi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(@NotNull GrAnnotationStub stub, @NotNull StubOutputStream dataStream) throws IOException {
|
||||
dataStream.writeName(stub.getAnnotationName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GrAnnotationStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
|
||||
return new GrAnnotationStub(parentStub, dataStream.readName());
|
||||
}
|
||||
};
|
||||
GrStubElementType<GrAnnotationStub, GrAnnotation> ANNOTATION = new GrAnnotationElementType("annotation");
|
||||
//parameters
|
||||
EmptyStubElementType<GrParameterList> PARAMETERS_LIST = new EmptyStubElementType<GrParameterList>("parameters list", GroovyFileType.GROOVY_LANGUAGE) {
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -523,7 +523,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
@NotNull
|
||||
@Override
|
||||
public GrAnnotation createAnnotationFromText(@NotNull @NonNls String annotationText, @Nullable PsiElement context) throws IncorrectOperationException {
|
||||
return createMethodFromText(annotationText + " void ___shdjklf_pqweirupncp_foo() {}", context).getModifierList().getAnnotations()[0];
|
||||
return createMethodFromText(annotationText + " void ___shdjklf_pqweirupncp_foo() {}", context).getModifierList().getRawAnnotations()[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+28
-6
@@ -82,20 +82,34 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
|
||||
|
||||
@NotNull
|
||||
public GrAnnotationArgumentList getParameterList() {
|
||||
final GrAnnotationStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getPsiElement().getParameterList();
|
||||
}
|
||||
return findNotNullChildByClass(GrAnnotationArgumentList.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNls
|
||||
public String getQualifiedName() {
|
||||
final GrAnnotationStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getPsiElement().getQualifiedName();
|
||||
}
|
||||
|
||||
final GrCodeReferenceElement nameRef = getClassReference();
|
||||
final PsiElement resolved = nameRef.resolve();
|
||||
if (resolved instanceof PsiClass) return ((PsiClass) resolved).getQualifiedName();
|
||||
if (resolved instanceof PsiClass) return ((PsiClass)resolved).getQualifiedName();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiJavaCodeReferenceElement getNameReferenceElement() {
|
||||
final GrAnnotationStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getPsiElement().getNameReferenceElement();
|
||||
}
|
||||
|
||||
final GroovyResolveResult resolveResult = getClassReference().advancedResolve();
|
||||
final PsiElement resolved = resolveResult.getElement();
|
||||
|
||||
@@ -107,6 +121,7 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiAnnotationMemberValue findAttributeValue(@Nullable String attributeName) {
|
||||
return PsiImplUtil.findAttributeValue(this, attributeName);
|
||||
}
|
||||
@@ -116,7 +131,7 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
|
||||
return PsiImplUtil.findDeclaredAttributeValue(this, attributeName);
|
||||
}
|
||||
|
||||
public <T extends PsiAnnotationMemberValue> T setDeclaredAttributeValue(@Nullable @NonNls String attributeName, T value) {
|
||||
public <T extends PsiAnnotationMemberValue> T setDeclaredAttributeValue(@Nullable @NonNls String attributeName, T value) {
|
||||
return (T)PsiImplUtil.setDeclaredAttributeValue(this, attributeName, value, ANNOTATION_CREATOR);
|
||||
}
|
||||
|
||||
@@ -127,6 +142,11 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
|
||||
|
||||
@NotNull
|
||||
public GrCodeReferenceElement getClassReference() {
|
||||
final GrAnnotationStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getPsiElement().getClassReference();
|
||||
}
|
||||
|
||||
return findNotNullChildByClass(GrCodeReferenceElement.class);
|
||||
}
|
||||
|
||||
@@ -134,13 +154,15 @@ public class GrAnnotationImpl extends GrStubElementBase<GrAnnotationStub> implem
|
||||
public String getShortName() {
|
||||
final GrAnnotationStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getAnnotationName();
|
||||
}
|
||||
else {
|
||||
return getClassReference().getReferenceName();
|
||||
return stub.getPsiElement().getShortName();
|
||||
}
|
||||
|
||||
final String referenceName = getClassReference().getReferenceName();
|
||||
assert referenceName != null;
|
||||
return referenceName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiAnnotationOwner getOwner() {
|
||||
return (PsiAnnotationOwner)getParent();
|
||||
}
|
||||
|
||||
+3
-2
@@ -42,6 +42,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
@@ -85,7 +86,7 @@ public class GrVariableDeclarationImpl extends GrStubElementBase<EmptyStub> impl
|
||||
|
||||
@NotNull
|
||||
public GrModifierList getModifierList() {
|
||||
return (GrModifierList)findNotNullChildByType(GroovyElementTypes.MODIFIERS);
|
||||
return getRequiredStubOrPsiChild(GroovyElementTypes.MODIFIERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -192,7 +193,7 @@ public class GrVariableDeclarationImpl extends GrStubElementBase<EmptyStub> impl
|
||||
@NotNull ResolveState state,
|
||||
PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
if (lastParent != null && lastParent == getTupleInitializer()) {
|
||||
if (lastParent != null && !(getParent() instanceof GrTypeDefinitionBody) && lastParent == getTupleInitializer()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+46
-7
@@ -1,28 +1,67 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.stubs;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.stubs.StubBase;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.util.io.StringRef;
|
||||
import com.intellij.reference.SoftReference;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class GrAnnotationStub extends StubBase<GrAnnotation> {
|
||||
private final StringRef myReference;
|
||||
private static final Logger LOG = Logger.getInstance(GrAnnotationStub.class);
|
||||
|
||||
public GrAnnotationStub(StubElement parent, StringRef reference) {
|
||||
private final String myText;
|
||||
private SoftReference<GrAnnotation> myPsiRef;
|
||||
|
||||
public GrAnnotationStub(StubElement parent, String text) {
|
||||
super(parent, GroovyElementTypes.ANNOTATION);
|
||||
myReference = reference;
|
||||
myText = text;
|
||||
}
|
||||
|
||||
public GrAnnotationStub(StubElement parent, GrAnnotation from) {
|
||||
super(parent, GroovyElementTypes.ANNOTATION);
|
||||
myReference = StringRef.fromString(from.getClassReference().getReferenceName());
|
||||
myText = from.getText();
|
||||
}
|
||||
|
||||
public String getAnnotationName() {
|
||||
return myReference.getString();
|
||||
public GrAnnotation getPsiElement() {
|
||||
if (myPsiRef != null) {
|
||||
final GrAnnotation annotation = myPsiRef.get();
|
||||
if (annotation != null) {
|
||||
return annotation;
|
||||
}
|
||||
}
|
||||
try {
|
||||
GrAnnotation annotation = GroovyPsiElementFactory.getInstance(getProject()).createAnnotationFromText(myText, getPsi());
|
||||
myPsiRef = new SoftReference<GrAnnotation>(annotation);
|
||||
return annotation;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error("Bad annotation in repository!", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return myText;
|
||||
}
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.stubs.elements;
|
||||
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.stubs.StubInputStream;
|
||||
import com.intellij.psi.stubs.StubOutputStream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrAnnotationStub;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 12/6/13
|
||||
*/
|
||||
public class GrAnnotationElementType extends GrStubElementType<GrAnnotationStub, GrAnnotation> {
|
||||
public GrAnnotationElementType(@NotNull String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrAnnotation createPsi(@NotNull GrAnnotationStub stub) {
|
||||
return new GrAnnotationImpl(stub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrAnnotationStub createStub(@NotNull GrAnnotation psi, StubElement parentStub) {
|
||||
return new GrAnnotationStub(parentStub, psi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(@NotNull GrAnnotationStub stub, @NotNull StubOutputStream dataStream) throws IOException {
|
||||
dataStream.writeUTFFast(stub.getText());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GrAnnotationStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
|
||||
return new GrAnnotationStub(parentStub, dataStream.readUTFFast());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -55,7 +55,7 @@ public class GrStubFileElementType extends IStubFileElementType<GrFileStub> {
|
||||
|
||||
@Override
|
||||
public int getStubVersion() {
|
||||
return super.getStubVersion() + 19;
|
||||
return super.getStubVersion() + 20;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+91
-3
@@ -15,14 +15,19 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.plugins.groovy.LightGroovyTestCase
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 12/4/13
|
||||
*/
|
||||
class GrStubAstSwitchTest extends LightCodeInsightFixtureTestCase {
|
||||
class GrStubAstSwitchTest extends LightGroovyTestCase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
null
|
||||
}
|
||||
|
||||
void testDontLoadContentWhenProcessingImports() {
|
||||
GroovyFileImpl file = (GroovyFileImpl) myFixture.addFileToProject("A.groovy", """
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
@@ -44,4 +49,87 @@ class B extends ConcurrentHashMap {
|
||||
fooMethod.findDeepestSuperMethods()
|
||||
assert !file.contentsLoaded
|
||||
}
|
||||
|
||||
void testDontLoadAstForAnnotation() {
|
||||
GroovyFileImpl file = myFixture.addFileToProject('a.groovy', '''\
|
||||
class A {
|
||||
def foo(){}
|
||||
}
|
||||
|
||||
class B {
|
||||
@Delegate
|
||||
A a = new A()
|
||||
}
|
||||
''') as GroovyFileImpl
|
||||
|
||||
assert !file.contentsLoaded
|
||||
PsiClass clazzB = file.classes[1]
|
||||
assert !file.contentsLoaded
|
||||
|
||||
PsiField field = clazzB.fields[0]
|
||||
assert !file.contentsLoaded
|
||||
|
||||
|
||||
PsiModifierList modifierList = field.modifierList
|
||||
assert !file.contentsLoaded
|
||||
|
||||
PsiAnnotation[] annotations = modifierList.annotations
|
||||
PsiAnnotation annotation = annotations[0]
|
||||
assert !file.contentsLoaded
|
||||
|
||||
assert annotation.qualifiedName == 'groovy.lang.Delegate'
|
||||
assert !file.contentsLoaded
|
||||
}
|
||||
|
||||
void testDontLoadAstForAnnotation2() {
|
||||
GroovyFileImpl file = myFixture.addFileToProject('a.groovy', '''\
|
||||
class A {
|
||||
def foo(){}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
@Override
|
||||
def foo() {}
|
||||
}
|
||||
''') as GroovyFileImpl
|
||||
|
||||
assert !file.contentsLoaded
|
||||
PsiClass clazzB = file.classes[1]
|
||||
assert !file.contentsLoaded
|
||||
|
||||
PsiMethod method = clazzB.methods[0]
|
||||
assert !file.contentsLoaded
|
||||
|
||||
|
||||
PsiModifierList modifierList = method.modifierList
|
||||
assert !file.contentsLoaded
|
||||
|
||||
PsiAnnotation[] annotations = modifierList.annotations
|
||||
PsiAnnotation annotation = annotations[0]
|
||||
assert !file.contentsLoaded
|
||||
|
||||
assert annotation.qualifiedName == "java.lang.Override"
|
||||
assert !file.contentsLoaded
|
||||
}
|
||||
|
||||
|
||||
void testDelegateExists() {
|
||||
GroovyFileImpl file = myFixture.addFileToProject('a.groovy', '''\
|
||||
class A {
|
||||
def foo(){}
|
||||
}
|
||||
|
||||
class B {
|
||||
@Delegate
|
||||
A a = new A()
|
||||
}
|
||||
''') as GroovyFileImpl
|
||||
|
||||
assert !file.contentsLoaded
|
||||
PsiClass clazzB = file.classes[1]
|
||||
assert !file.contentsLoaded
|
||||
|
||||
assert clazzB.methods.find {it.name =='foo'}
|
||||
assert !file.contentsLoaded
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ group.hg4idea.file.menu.text=Mercurial
|
||||
action.hg4idea.tag.text=Tag Repository...
|
||||
action.hg4idea.tag.description=Create a tag for current revision
|
||||
action.hg4idea.updateTo.text=Update to...
|
||||
action.hg4idea.updateTo.description=Updating to {0}...
|
||||
action.hg4idea.updateTo.description=Update the repository's working directory to the specified changeset.
|
||||
action.hg4idea.push.text=Push...
|
||||
action.hg4idea.push.description=Push outgoing commits
|
||||
action.hg4idea.pull.text=Pull...
|
||||
@@ -102,6 +102,7 @@ hg4idea.progress.updatingworkingdir=Updating local working directory
|
||||
hg4idea.progress.integrating=Integrating {0} ...
|
||||
hg4idea.progress.merging=Performing merge...
|
||||
hg4idea.progress.updating=Updating {0} ...
|
||||
hg4idea.progress.updatingTo=Updating to {0}...
|
||||
hg4idea.progress.countingHeads=Checking number of heads...
|
||||
hg4idea.progress.pull.with.rebase=Rebasing patches
|
||||
hg4idea.progress.pull.with.update=Updating repository
|
||||
|
||||
@@ -57,7 +57,7 @@ public class HgUpdateToAction extends HgAbstractGlobalAction {
|
||||
String updateToValue = dialog.isBranchSelected()
|
||||
? dialog.getBranch().getName()
|
||||
: dialog.isTagSelected() ? dialog.getTag().getName() : dialog.getRevision();
|
||||
new Task.Backgroundable(project, HgVcsMessages.message("action.hg4idea.updateTo.description", updateToValue)) {
|
||||
new Task.Backgroundable(project, HgVcsMessages.message("hg4idea.progress.updatingTo", updateToValue)) {
|
||||
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.lang.properties.xml;
|
||||
|
||||
import com.intellij.ide.highlighter.XmlFileType;
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.PropertiesUtil;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
@@ -71,7 +72,7 @@ public class XmlPropertiesFile implements PropertiesFile {
|
||||
|
||||
@Nullable
|
||||
public static PropertiesFile getPropertiesFile(final PsiFile file) {
|
||||
return file instanceof XmlFile ? getPropertiesFile((XmlFile)file) : null;
|
||||
return file instanceof XmlFile && file.getFileType() == XmlFileType.INSTANCE ? getPropertiesFile((XmlFile)file) : null;
|
||||
}
|
||||
|
||||
public static PropertiesFile getPropertiesFile(final XmlFile file) {
|
||||
|
||||
+4
-1
@@ -1,6 +1,7 @@
|
||||
package com.intellij.lang.properties.xml;
|
||||
|
||||
import com.intellij.ide.IconProvider;
|
||||
import com.intellij.ide.highlighter.XmlFileType;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import icons.PropertiesIcons;
|
||||
@@ -16,6 +17,8 @@ public class XmlPropertiesIconProvider extends IconProvider {
|
||||
|
||||
@Override
|
||||
public Icon getIcon(@NotNull PsiElement element, int flags) {
|
||||
return element instanceof XmlFile && XmlPropertiesFile.getPropertiesFile((XmlFile)element) != null ? PropertiesIcons.XmlProperties : null;
|
||||
return element instanceof XmlFile &&
|
||||
((XmlFile)element).getFileType() == XmlFileType.INSTANCE &&
|
||||
XmlPropertiesFile.getPropertiesFile((XmlFile)element) != null ? PropertiesIcons.XmlProperties : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,31 +86,26 @@ public final class DomManagerImpl extends DomManager {
|
||||
private final SemService mySemService;
|
||||
private final ConverterManager myConverterManager;
|
||||
private final DomApplicationComponent myApplicationComponent;
|
||||
private final PsiFileFactory myFileFactory;
|
||||
private final ProjectFileIndex myFileIndex;
|
||||
|
||||
private long myModificationCount;
|
||||
private boolean myChanging;
|
||||
|
||||
public DomManagerImpl(Project project,
|
||||
final XmlAspect xmlAspect,
|
||||
SemService semService,
|
||||
ConverterManager converterManager,
|
||||
DomApplicationComponent appComponent,
|
||||
PsiFileFactory fileFactory,
|
||||
ProjectFileIndex fileIndex) {
|
||||
DomApplicationComponent appComponent) {
|
||||
myProject = project;
|
||||
mySemService = semService;
|
||||
myConverterManager = converterManager;
|
||||
myApplicationComponent = appComponent;
|
||||
myFileFactory = fileFactory;
|
||||
myFileIndex = fileIndex;
|
||||
|
||||
PomModel pomModel = PomManager.getModel(project);
|
||||
final PomModel pomModel = PomManager.getModel(project);
|
||||
pomModel.addModelListener(new PomModelListener() {
|
||||
public void modelChanged(PomModelEvent event) {
|
||||
final XmlChangeSet changeSet = (XmlChangeSet)event.getChangeSet(xmlAspect);
|
||||
if (changeSet != null && !myChanging) {
|
||||
if (myChanging) return;
|
||||
|
||||
final XmlChangeSet changeSet = (XmlChangeSet)event.getChangeSet(pomModel.getModelAspect(XmlAspect.class));
|
||||
if (changeSet != null) {
|
||||
for (XmlFile file : changeSet.getChangedFiles()) {
|
||||
DomFileElementImpl<DomElement> element = getCachedFileElement(file);
|
||||
if (element != null) {
|
||||
@@ -121,7 +116,7 @@ public final class DomManagerImpl extends DomManager {
|
||||
}
|
||||
|
||||
public boolean isAspectChangeInteresting(PomModelAspect aspect) {
|
||||
return xmlAspect.equals(aspect);
|
||||
return aspect instanceof XmlAspect;
|
||||
}
|
||||
}, project);
|
||||
|
||||
@@ -234,7 +229,7 @@ public final class DomManagerImpl extends DomManager {
|
||||
}
|
||||
|
||||
private void processFileOrDirectoryChange(final VirtualFile file) {
|
||||
if (!myFileIndex.isInContent(file)) return;
|
||||
if (!ProjectFileIndex.SERVICE.getInstance(myProject).isInContent(file)) return;
|
||||
if (!file.isDirectory()) {
|
||||
processFileChange(file);
|
||||
} else {
|
||||
@@ -444,7 +439,7 @@ public final class DomManagerImpl extends DomManager {
|
||||
}
|
||||
|
||||
public final <T extends DomElement> T createMockElement(final Class<T> aClass, final Module module, final boolean physical) {
|
||||
final XmlFile file = (XmlFile)myFileFactory.createFileFromText("a.xml", StdFileTypes.XML, "", (long)0, physical);
|
||||
final XmlFile file = (XmlFile)PsiFileFactory.getInstance(myProject).createFileFromText("a.xml", StdFileTypes.XML, "", (long)0, physical);
|
||||
file.putUserData(MOCK_ELEMENT_MODULE, module);
|
||||
file.putUserData(MOCK, new Object());
|
||||
return getFileElement(file, aClass, "I_sincerely_hope_that_nobody_will_have_such_a_root_tag_name").getRootElement();
|
||||
|
||||
Reference in New Issue
Block a user