mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git@git.labs.intellij.net:idea/community
This commit is contained in:
Generated
+2
-34
@@ -3,16 +3,8 @@
|
||||
<component name="BuildJarProjectSettings">
|
||||
<option name="BUILD_JARS_ON_MAKE" value="false" />
|
||||
</component>
|
||||
<component name="CompilerAPISettings">
|
||||
<option name="DEBUGGING_INFO" value="true" />
|
||||
<option name="GENERATE_NO_WARNINGS" value="false" />
|
||||
<option name="DEPRECATION" value="true" />
|
||||
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
||||
<option name="MAXIMUM_HEAP_SIZE" value="128" />
|
||||
</component>
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||
<option name="DEPLOY_AFTER_MAKE" value="0" />
|
||||
<resourceExtensions>
|
||||
<entry name=".+\.(properties|xml|html|dtd|tld)" />
|
||||
<entry name=".+\.(gif|png|jpeg|jpg)" />
|
||||
@@ -23,42 +15,18 @@
|
||||
<entry name="!*.class" />
|
||||
<entry name="!*.groovy" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing enabled="false" useClasspath="true" />
|
||||
</component>
|
||||
<component name="EclipseCompilerSettings">
|
||||
<option name="DEBUGGING_INFO" value="true" />
|
||||
<option name="GENERATE_NO_WARNINGS" value="true" />
|
||||
<option name="DEPRECATION" value="false" />
|
||||
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
||||
<option name="MAXIMUM_HEAP_SIZE" value="128" />
|
||||
</component>
|
||||
<component name="EclipseEmbeddedCompilerSettings">
|
||||
<option name="DEBUGGING_INFO" value="true" />
|
||||
<option name="GENERATE_NO_WARNINGS" value="true" />
|
||||
<option name="DEPRECATION" value="false" />
|
||||
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
||||
<option name="MAXIMUM_HEAP_SIZE" value="128" />
|
||||
</component>
|
||||
<component name="JavacSettings">
|
||||
<option name="DEBUGGING_INFO" value="true" />
|
||||
<option name="GENERATE_NO_WARNINGS" value="false" />
|
||||
<option name="DEPRECATION" value="true" />
|
||||
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
||||
<option name="MAXIMUM_HEAP_SIZE" value="128" />
|
||||
</component>
|
||||
<component name="JikesSettings">
|
||||
<option name="JIKES_PATH" value="" />
|
||||
<option name="DEBUGGING_INFO" value="true" />
|
||||
<option name="DEPRECATION" value="true" />
|
||||
<option name="GENERATE_NO_WARNINGS" value="false" />
|
||||
<option name="IS_EMACS_ERRORS_MODE" value="true" />
|
||||
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
||||
</component>
|
||||
<component name="RmicSettings">
|
||||
<option name="IS_EANABLED" value="false" />
|
||||
<option name="DEBUGGING_INFO" value="true" />
|
||||
<option name="GENERATE_NO_WARNINGS" value="false" />
|
||||
<option name="GENERATE_IIOP_STUBS" value="false" />
|
||||
<option name="ADDITIONAL_OPTIONS_STRING" value="" />
|
||||
<option name="MAXIMUM_HEAP_SIZE" value="200" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
|
||||
+3
-3
@@ -13,12 +13,12 @@ public class AuxiliaryCallsFolding extends ConsoleFolding {
|
||||
@Override
|
||||
public boolean shouldFoldLine(String line) {
|
||||
final Trinity<String, String, TextRange> pair = ExceptionFilter.parseExceptionLine(line);
|
||||
return pair != null && shouldFold(pair.first);
|
||||
return pair != null && shouldFold(pair.first, pair.second);
|
||||
}
|
||||
|
||||
private static boolean shouldFold(String className) {
|
||||
private static boolean shouldFold(String className, String methodName) {
|
||||
for (StackFrameFilter provider : StackFrameFilter.EP_NAME.getExtensions()) {
|
||||
if (provider.isAuxiliaryFrame(className, "")) {
|
||||
if (provider.isAuxiliaryFrame(className, methodName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,13 +74,12 @@ public class ExceptionFilter implements Filter, DumbAware {
|
||||
if (lastDotIndex < 0 || lastDotIndex < atIndex) return null;
|
||||
String className = line.substring(atIndex + AT.length() + 1, lastDotIndex).trim();
|
||||
|
||||
//String methodName = text.substring(lastDotIndex + 1, lparenthIndex).trim();
|
||||
String methodName = line.substring(lastDotIndex + 1, lparenthIndex).trim();
|
||||
|
||||
final int rparenthIndex = line.indexOf(')', lparenthIndex);
|
||||
if (rparenthIndex < 0) return null;
|
||||
|
||||
final String fileAndLine = line.substring(lparenthIndex + 1, rparenthIndex).trim();
|
||||
return Trinity.create(className, fileAndLine, new TextRange(lparenthIndex, rparenthIndex));
|
||||
return Trinity.create(className, methodName, new TextRange(lparenthIndex, rparenthIndex));
|
||||
}
|
||||
|
||||
public Result applyFilter(final String line, final int textEndOffset) {
|
||||
@@ -95,7 +94,9 @@ public class ExceptionFilter implements Filter, DumbAware {
|
||||
className = className.substring(0, dollarIndex);
|
||||
}
|
||||
|
||||
final String fileAndLine = info.second;
|
||||
final int lparenthIndex = info.third.getStartOffset();
|
||||
final int rparenthIndex = info.third.getEndOffset();
|
||||
final String fileAndLine = line.substring(lparenthIndex + 1, rparenthIndex).trim();
|
||||
|
||||
final int colonIndex = fileAndLine.lastIndexOf(':');
|
||||
if (colonIndex < 0) return null;
|
||||
@@ -118,8 +119,9 @@ public class ExceptionFilter implements Filter, DumbAware {
|
||||
*/
|
||||
|
||||
final int textStartOffset = textEndOffset - line.length();
|
||||
final int highlightStartOffset = textStartOffset + info.third.getStartOffset() + 1;
|
||||
final int highlightEndOffset = textStartOffset + info.third.getEndOffset();
|
||||
|
||||
final int highlightStartOffset = textStartOffset + lparenthIndex + 1;
|
||||
final int highlightEndOffset = textStartOffset + rparenthIndex;
|
||||
VirtualFile virtualFile = file.getVirtualFile();
|
||||
final OpenFileHyperlinkInfo linkInfo = new OpenFileHyperlinkInfo(myProject, virtualFile, lineNumber - 1);
|
||||
TextAttributes attributes = HYPERLINK_ATTRIBUTES.clone();
|
||||
|
||||
+7
@@ -5,6 +5,13 @@ package com.intellij.execution.filters;
|
||||
*/
|
||||
public class ReflectionStackFrameFilter extends StackFrameFilter {
|
||||
public boolean isAuxiliaryFrame(String className, String methodName) {
|
||||
if (className.equals("java.lang.reflect.Method") && methodName.equals("invoke")) {
|
||||
return true;
|
||||
}
|
||||
if (className.equals("java.lang.reflect.Constructor") && methodName.equals("newInstance")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return className.startsWith("sun.reflect.");
|
||||
}
|
||||
}
|
||||
|
||||
+23
-10
@@ -53,24 +53,26 @@ public class PsiMethodInsertHandler implements InsertHandler<LookupItem<PsiMetho
|
||||
final TailType tailType = getTailType(item, context);
|
||||
final Document document = editor.getDocument();
|
||||
final PsiFile file = context.getFile();
|
||||
final int offset = editor.getCaretModel().getOffset();
|
||||
|
||||
context.setAddCompletionChar(false);
|
||||
|
||||
final LookupElement[] allItems = context.getElements();
|
||||
boolean signatureSelected = allItems.length > 1 || item.getUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) != null;
|
||||
final boolean overloadsMatter = allItems.length == 1 && item.getUserData(LookupItem.FORCE_SHOW_SIGNATURE_ATTR) == null;
|
||||
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
final boolean hasParams = MethodParenthesesHandler.hasParams(item, allItems, overloadsMatter, myMethod);
|
||||
final boolean needLeftParenth = isToInsertParenth(file.findElementAt(context.getStartOffset()));
|
||||
final boolean hasParams = MethodParenthesesHandler.hasParams(item, allItems, !signatureSelected, myMethod);
|
||||
final boolean needRightParenth = shouldInsertRParenth(completionChar, tailType, hasParams);
|
||||
|
||||
if (needLeftParenth) {
|
||||
final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(context.getProject());
|
||||
new MethodParenthesesHandler(myMethod, !signatureSelected,
|
||||
new MethodParenthesesHandler(myMethod, overloadsMatter,
|
||||
styleSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES,
|
||||
styleSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES && hasParams,
|
||||
shouldInsertRightParenthesis(tailType)
|
||||
needRightParenth
|
||||
).handleInsert(context, item);
|
||||
}
|
||||
|
||||
|
||||
insertExplicitTypeParams(item, document, offset, file);
|
||||
|
||||
final PsiType type = myMethod.getReturnType();
|
||||
@@ -86,14 +88,25 @@ public class PsiMethodInsertHandler implements InsertHandler<LookupItem<PsiMetho
|
||||
|
||||
if (needLeftParenth && hasParams) {
|
||||
// Invoke parameters popup
|
||||
AutoPopupController.getInstance(myMethod.getProject()).autoPopupParameterInfo(editor, signatureSelected ? myMethod : null);
|
||||
AutoPopupController.getInstance(myMethod.getProject()).autoPopupParameterInfo(editor, overloadsMatter ? null : myMethod);
|
||||
}
|
||||
if (tailType == TailType.SMART_COMPLETION || needLeftParenth && needRightParenth) {
|
||||
tailType.processTail(editor, context.getTailOffset());
|
||||
}
|
||||
tailType.processTail(editor, context.getTailOffset());
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
}
|
||||
|
||||
protected static boolean shouldInsertRightParenthesis(TailType tailType) {
|
||||
return tailType != TailType.SMART_COMPLETION;
|
||||
private boolean shouldInsertRParenth(char completionChar, TailType tailType, boolean hasParams) {
|
||||
if (tailType == TailType.SMART_COMPLETION) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (completionChar == '(' && !hasParams) {
|
||||
//it's highly probable that the user will type ')' next and it may not be overwritten if the flag is off
|
||||
return CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+5
-1
@@ -30,6 +30,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
@@ -89,7 +90,10 @@ public class CopyPasteReferenceProcessor implements CopyPastePostProcessor {
|
||||
ReferenceTransferableData referenceData = null;
|
||||
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE != CodeInsightSettings.NO) {
|
||||
try {
|
||||
referenceData = (ReferenceTransferableData)content.getTransferData(ReferenceTransferableData.ReferenceData.FLAVOR);
|
||||
final DataFlavor flavor = ReferenceTransferableData.ReferenceData.getDataFlavor();
|
||||
if (flavor != null) {
|
||||
referenceData = (ReferenceTransferableData)content.getTransferData(flavor);
|
||||
}
|
||||
}
|
||||
catch (UnsupportedFlavorException ignored) {
|
||||
}
|
||||
|
||||
+15
-4
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
@@ -32,7 +31,7 @@ public class ReferenceTransferableData implements TextBlockTransferableData, Clo
|
||||
}
|
||||
|
||||
public DataFlavor getFlavor() {
|
||||
return ReferenceData.FLAVOR;
|
||||
return ReferenceData.getDataFlavor();
|
||||
}
|
||||
|
||||
public int getOffsetCount() {
|
||||
@@ -68,8 +67,7 @@ public class ReferenceTransferableData implements TextBlockTransferableData, Clo
|
||||
}
|
||||
|
||||
public static class ReferenceData implements Cloneable, Serializable {
|
||||
public static final @NonNls DataFlavor FLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType+";class="+ReferenceData.class.getName(),
|
||||
CodeInsightBundle.message("paste.dataflavor.referencedata"));
|
||||
public static @NonNls DataFlavor ourFlavor;
|
||||
|
||||
public int startOffset;
|
||||
public int endOffset;
|
||||
@@ -91,5 +89,18 @@ public class ReferenceTransferableData implements TextBlockTransferableData, Clo
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static DataFlavor getDataFlavor() {
|
||||
if (ourFlavor != null) {
|
||||
return ourFlavor;
|
||||
}
|
||||
try {
|
||||
ourFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + ReferenceData.class.getName(), "ReferenceData");
|
||||
}
|
||||
catch (NoClassDefFoundError e) {
|
||||
return null;
|
||||
}
|
||||
return ourFlavor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.psi.impl.file;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
|
||||
/**
|
||||
@@ -30,7 +29,7 @@ public class JavaUpdateAddedFileProcessor extends UpdateAddedFileProcessor {
|
||||
}
|
||||
|
||||
public void update(final PsiFile element, PsiFile originalElement) throws IncorrectOperationException {
|
||||
if (PsiUtilBase.getTemplateLanguageFile(element) != element.getContainingFile()) return;
|
||||
if (element.getViewProvider().getLanguages().size() > 1) return;
|
||||
|
||||
PsiDirectory dir = element.getContainingDirectory();
|
||||
if (dir == null) return;
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class MyClass {
|
||||
|
||||
void foo() {}
|
||||
|
||||
{
|
||||
fo<caret>
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class MyClass {
|
||||
|
||||
void foo() {}
|
||||
|
||||
{
|
||||
foo(<caret>
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class MyClass {
|
||||
|
||||
void foo() {}
|
||||
|
||||
{
|
||||
foo();<caret>
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -3,6 +3,6 @@ class MyClass {
|
||||
void foo() {}
|
||||
|
||||
{
|
||||
foo();<caret>
|
||||
foo(<caret>);
|
||||
}
|
||||
}
|
||||
@@ -308,6 +308,25 @@ public class NormalCompletionTest extends LightCompletionTestCase {
|
||||
checkResultByFile("/codeInsight/completion/normal/MethodWithLeftParTailType2_after.java");
|
||||
}
|
||||
|
||||
public void testMethodWithLeftParTailTypeNoPairBrace() throws Exception {
|
||||
final boolean old = CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET;
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = false;
|
||||
|
||||
try {
|
||||
configureByFile("/codeInsight/completion/normal/" + getTestName(false) + ".java");
|
||||
selectItem(myItems[0], '(');
|
||||
checkResultByFile("/codeInsight/completion/normal/" + getTestName(false) + "_after.java");
|
||||
|
||||
//no tail type should work the normal way
|
||||
configureByFile("/codeInsight/completion/normal/" + getTestName(false) + ".java");
|
||||
selectItem(myItems[0]);
|
||||
checkResultByFile("/codeInsight/completion/normal/" + getTestName(false) + "_after2.java");
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET = old;
|
||||
}
|
||||
}
|
||||
|
||||
public void testExcessSpaceInTypeCast() throws Throwable {
|
||||
configureByFile("/codeInsight/completion/normal/" + getTestName(false) + ".java");
|
||||
selectItem(myItems[0]);
|
||||
|
||||
+4
-4
@@ -72,9 +72,9 @@ public abstract class ParenthesesInsertHandler<T extends LookupElement> implemen
|
||||
final Document document = editor.getDocument();
|
||||
PsiElement element = findNextToken(context);
|
||||
|
||||
final boolean hasParams = placeCaretInsideParentheses(context, item);
|
||||
|
||||
final char completionChar = context.getCompletionChar();
|
||||
final boolean putCaretInside = completionChar == '(' || placeCaretInsideParentheses(context, item);
|
||||
|
||||
if (completionChar == '(') {
|
||||
context.setAddCompletionChar(false);
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public abstract class ParenthesesInsertHandler<T extends LookupElement> implemen
|
||||
if (isToken(last, ")")) {
|
||||
int rparenthOffset = last.getTextRange().getStartOffset();
|
||||
context.setTailOffset(rparenthOffset + 1);
|
||||
if (!hasParams) {
|
||||
if (!putCaretInside) {
|
||||
for (int i = lparenthOffset + 1; i < rparenthOffset; i++) {
|
||||
if (!Character.isWhitespace(document.getCharsSequence().charAt(i))) {
|
||||
return;
|
||||
@@ -132,7 +132,7 @@ public abstract class ParenthesesInsertHandler<T extends LookupElement> implemen
|
||||
tailOffset = TailType.insertChar(editor, tailOffset, ' ');
|
||||
}
|
||||
document.insertString(tailOffset, ")");
|
||||
editor.getCaretModel().moveToOffset(hasParams ? caret : context.getTailOffset());
|
||||
editor.getCaretModel().moveToOffset(putCaretInside ? caret : context.getTailOffset());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+5
-2
@@ -24,6 +24,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.codeInsight.folding.CodeFoldingManager;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.util.ArrayList;
|
||||
@@ -59,8 +60,10 @@ public class CopyPasteFoldingProcessor implements CopyPastePostProcessor {
|
||||
public TextBlockTransferableData extractTransferableData(final Transferable content) {
|
||||
FoldingTransferableData foldingData = null;
|
||||
try {
|
||||
foldingData =
|
||||
(FoldingTransferableData)content.getTransferData(FoldingTransferableData.FoldingData.FLAVOR);
|
||||
final DataFlavor flavor = FoldingTransferableData.FoldingData.getDataFlavor();
|
||||
if (flavor != null) {
|
||||
foldingData = (FoldingTransferableData)content.getTransferData(flavor);
|
||||
}
|
||||
}
|
||||
catch (UnsupportedFlavorException e) {
|
||||
}
|
||||
|
||||
+15
-4
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
@@ -30,7 +29,7 @@ public class FoldingTransferableData implements TextBlockTransferableData, Seria
|
||||
}
|
||||
|
||||
public DataFlavor getFlavor() {
|
||||
return FoldingData.FLAVOR;
|
||||
return FoldingData.getDataFlavor();
|
||||
}
|
||||
|
||||
public int getOffsetCount() {
|
||||
@@ -66,8 +65,7 @@ public class FoldingTransferableData implements TextBlockTransferableData, Seria
|
||||
}
|
||||
|
||||
public static class FoldingData implements Cloneable, Serializable {
|
||||
public static final @NonNls DataFlavor FLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + FoldingData.class.getName(),
|
||||
CodeInsightBundle.message("paste.data.flavor.folding"));
|
||||
private static @NonNls DataFlavor ourFlavor;
|
||||
|
||||
public int startOffset;
|
||||
public int endOffset;
|
||||
@@ -87,5 +85,18 @@ public class FoldingTransferableData implements TextBlockTransferableData, Seria
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static DataFlavor getDataFlavor() {
|
||||
if (ourFlavor != null) {
|
||||
return ourFlavor;
|
||||
}
|
||||
try {
|
||||
ourFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + FoldingData.class.getName(), "FoldingData");
|
||||
}
|
||||
catch (NoClassDefFoundError e) {
|
||||
return null;
|
||||
}
|
||||
return ourFlavor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,6 @@ import com.intellij.util.text.CharArrayUtil;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
@@ -153,14 +151,7 @@ public class PasteHandler extends EditorActionHandler {
|
||||
);
|
||||
}
|
||||
|
||||
RawText rawText = null;
|
||||
try {
|
||||
rawText = (RawText)content.getTransferData(RawText.FLAVOR);
|
||||
}
|
||||
catch (UnsupportedFlavorException e) {
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
RawText rawText = RawText.fromTransferable(content);
|
||||
|
||||
String newText = text;
|
||||
for(CopyPastePreProcessor preProcessor: Extensions.getExtensions(CopyPastePreProcessor.EP_NAME)) {
|
||||
|
||||
+12
-4
@@ -17,6 +17,7 @@
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.openapi.editor.RawText;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
@@ -41,9 +42,16 @@ class TextBlockTransferable implements Transferable {
|
||||
myRawText = rawText;
|
||||
|
||||
List<DataFlavor> dataFlavors = new ArrayList<DataFlavor>();
|
||||
Collections.addAll(dataFlavors, DataFlavor.stringFlavor, DataFlavor.plainTextFlavor, RawText.FLAVOR);
|
||||
Collections.addAll(dataFlavors, DataFlavor.stringFlavor, DataFlavor.plainTextFlavor);
|
||||
final DataFlavor flavor = RawText.getDataFlavor();
|
||||
if (flavor != null) {
|
||||
dataFlavors.add(flavor);
|
||||
}
|
||||
for(TextBlockTransferableData data: extraData) {
|
||||
dataFlavors.add(data.getFlavor());
|
||||
final DataFlavor blockFlavor = data.getFlavor();
|
||||
if (blockFlavor != null) {
|
||||
dataFlavors.add(blockFlavor);
|
||||
}
|
||||
}
|
||||
myTransferDataFlavors = dataFlavors.toArray(new DataFlavor[dataFlavors.size()]);
|
||||
}
|
||||
@@ -65,11 +73,11 @@ class TextBlockTransferable implements Transferable {
|
||||
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||
try {
|
||||
for(TextBlockTransferableData data: myExtraData) {
|
||||
if (data.getFlavor().equals(flavor)) {
|
||||
if (Comparing.equal(data.getFlavor(), flavor)) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
if (RawText.FLAVOR.equals(flavor)) {
|
||||
if (Comparing.equal(RawText.getDataFlavor(), flavor)) {
|
||||
return myRawText;
|
||||
}
|
||||
else if (DataFlavor.stringFlavor.equals(flavor)) {
|
||||
|
||||
@@ -141,17 +141,7 @@ public class EditorModificationUtil {
|
||||
}
|
||||
|
||||
private static String getStringContent(final Transferable content) throws UnsupportedFlavorException, IOException {
|
||||
RawText raw = null;
|
||||
try {
|
||||
raw = (RawText)content.getTransferData(RawText.FLAVOR);
|
||||
}
|
||||
catch (UnsupportedFlavorException e) {
|
||||
// OK. raw will be null and we'll get plain string
|
||||
}
|
||||
catch (IOException e) {
|
||||
// OK. raw will be null and we'll get plain string
|
||||
}
|
||||
|
||||
RawText raw = RawText.fromTransferable(content);
|
||||
String s;
|
||||
if (raw != null) {
|
||||
s = raw.rawText;
|
||||
|
||||
@@ -23,13 +23,16 @@
|
||||
package com.intellij.openapi.editor;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class RawText implements Cloneable, Serializable {
|
||||
public static final @NonNls DataFlavor FLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + RawText.class.getName(),
|
||||
"Raw Text");
|
||||
public static @NonNls DataFlavor ourFlavor;
|
||||
public String rawText;
|
||||
|
||||
public RawText(final String rawText) {
|
||||
@@ -44,4 +47,35 @@ public class RawText implements Cloneable, Serializable {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public static DataFlavor getDataFlavor() {
|
||||
if (ourFlavor != null) {
|
||||
return ourFlavor;
|
||||
}
|
||||
try {
|
||||
ourFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + RawText.class.getName(), "Raw Text");
|
||||
}
|
||||
catch (NoClassDefFoundError e) {
|
||||
return null;
|
||||
}
|
||||
return ourFlavor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static RawText fromTransferable(Transferable content) {
|
||||
RawText raw = null;
|
||||
final DataFlavor flavor = getDataFlavor();
|
||||
if (flavor != null) {
|
||||
try {
|
||||
raw = (RawText)content.getTransferData(flavor);
|
||||
}
|
||||
catch (UnsupportedFlavorException e) {
|
||||
// OK. raw will be null and we'll get plain string
|
||||
}
|
||||
catch (IOException e) {
|
||||
// OK. raw will be null and we'll get plain string
|
||||
}
|
||||
}
|
||||
return raw;
|
||||
}
|
||||
}
|
||||
+12
-1
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiConstantEvaluationHelper;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -51,6 +53,12 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
private List<InstructionImpl> myInstructions;
|
||||
|
||||
private Stack<InstructionImpl> myProcessingStack;
|
||||
private PsiConstantEvaluationHelper myConstantEvaluator;
|
||||
|
||||
public ControlFlowBuilder(Project project) {
|
||||
myConstantEvaluator = JavaPsiFacade.getInstance(project).getConstantEvaluationHelper();
|
||||
|
||||
}
|
||||
|
||||
private class ExceptionInfo {
|
||||
GrCatchClause myClause;
|
||||
@@ -485,7 +493,10 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
|
||||
if (condition != null) {
|
||||
condition.accept(this);
|
||||
}
|
||||
addPendingEdge(whileStatement, myHead); //break
|
||||
final boolean endless = Boolean.TRUE.equals(myConstantEvaluator.computeConstantExpression(condition));
|
||||
if (!endless) {
|
||||
addPendingEdge(whileStatement, myHead); //break
|
||||
}
|
||||
final GrCondition body = whileStatement.getBody();
|
||||
if (body != null) {
|
||||
body.accept(this);
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ public abstract class GroovyFileBaseImpl extends PsiFileBase implements GroovyFi
|
||||
|
||||
public Instruction[] getControlFlow() {
|
||||
if (myControlFlow == null) {
|
||||
myControlFlow = new ControlFlowBuilder().buildControlFlow(this, null, null);
|
||||
myControlFlow = new ControlFlowBuilder(getProject()).buildControlFlow(this, null, null);
|
||||
}
|
||||
|
||||
return myControlFlow;
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ public abstract class GrBlockImpl extends GroovyPsiElementImpl implements GrCode
|
||||
|
||||
public Instruction[] getControlFlow() {
|
||||
if (myControlFlow == null) {
|
||||
myControlFlow = new ControlFlowBuilder().buildControlFlow(this, null, null);
|
||||
myControlFlow = new ControlFlowBuilder(getProject()).buildControlFlow(this, null, null);
|
||||
}
|
||||
|
||||
return myControlFlow;
|
||||
|
||||
@@ -33,6 +33,7 @@ public class MissingReturnTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testMissingReturnOvertReturnType() throws Throwable {doTest();}
|
||||
public void testMissingReturnFromClosure() throws Throwable {doTest();}
|
||||
public void testReturnsWithoutValue() throws Throwable {doTest();}
|
||||
public void testEndlessLoop() throws Throwable {doTest();}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
myFixture.enableInspections(new MissingReturnInspection());
|
||||
|
||||
+2
-1
@@ -44,6 +44,7 @@ public class ControlFlowTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testTry7() throws Throwable { doTest(); }
|
||||
public void testWhile1() throws Throwable { doTest(); }
|
||||
public void testWhile2() throws Throwable { doTest(); }
|
||||
public void testWhileNonConstant() throws Throwable { doTest(); }
|
||||
public void testIfInstanceofElse() throws Throwable { doTest(); }
|
||||
|
||||
private static String dumpControlFlow(Instruction[] instructions) {
|
||||
@@ -66,7 +67,7 @@ public class ControlFlowTest extends LightCodeInsightFixtureTestCase {
|
||||
final PsiElement start = file.findElementAt(model.hasSelection() ? model.getSelectionStart() : 0);
|
||||
final PsiElement end = file.findElementAt(model.hasSelection() ? model.getSelectionEnd() - 1 : file.getTextLength() - 1);
|
||||
final GrControlFlowOwner owner = PsiTreeUtil.getParentOfType(PsiTreeUtil.findCommonParent(start, end), GrControlFlowOwner.class, false);
|
||||
final Instruction[] instructions = new ControlFlowBuilder().buildControlFlow(owner, null, null);
|
||||
final Instruction[] instructions = new ControlFlowBuilder(getProject()).buildControlFlow(owner, null, null);
|
||||
final String cf = dumpControlFlow(instructions);
|
||||
assertEquals(input.get(1).trim(), cf.trim());
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ class Foo {
|
||||
def bar
|
||||
}
|
||||
|
||||
new Foo().getBar()<caret>
|
||||
new Foo().getBar(<caret>)
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ while (true) {
|
||||
-----
|
||||
0(1) element: null
|
||||
1(2) WRITE i
|
||||
2(3,7) element: WHILE statement
|
||||
2(3) element: WHILE statement
|
||||
3(4,5) element: IF statement
|
||||
4(7) READ i
|
||||
5(6) READ i
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ while (true) {
|
||||
-----
|
||||
0(1) element: null
|
||||
1(2) WRITE i
|
||||
2(3,7) element: WHILE statement
|
||||
2(3) element: WHILE statement
|
||||
3(4,5) element: IF statement
|
||||
4(2) READ i
|
||||
5(6) READ i
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
i = 0
|
||||
while (condition()) {
|
||||
if (i > 10) break
|
||||
i++
|
||||
}
|
||||
-----
|
||||
0(1) element: null
|
||||
1(2) WRITE i
|
||||
2(3) element: WHILE statement
|
||||
3(4,8) READ condition
|
||||
4(5,6) element: IF statement
|
||||
5(8) READ i
|
||||
6(7) READ i
|
||||
7(2) WRITE i
|
||||
8() element: null
|
||||
@@ -12,9 +12,10 @@ def i = 6
|
||||
println i
|
||||
-----
|
||||
def i = 6
|
||||
i = <caret>testMethod(i)
|
||||
i = testMethod()
|
||||
|
||||
private int testMethod(int i) {
|
||||
private int testMethod() {
|
||||
int i
|
||||
while (true) {
|
||||
println "preved"
|
||||
i = 42
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
def foo() {
|
||||
while (true) {
|
||||
return 239
|
||||
}
|
||||
}
|
||||
@@ -41,9 +41,8 @@ public abstract class DomModelFactory<T extends DomElement, M extends DomModel<T
|
||||
}
|
||||
|
||||
protected Module getModelScope(final XmlFile file) {
|
||||
final Module module = ModuleUtil.findModuleForPsiElement(file);
|
||||
|
||||
return module;
|
||||
return ModuleUtil.findModuleForPsiElement(file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package com.intellij.util.xml.model.impl;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomFileElement;
|
||||
import com.intellij.util.xml.MergedObject;
|
||||
import com.intellij.util.xml.DomUtil;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.xml.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -34,24 +34,42 @@ public class DomModelImpl<T extends DomElement> {
|
||||
|
||||
protected final DomFileElement<T> myMergedModel;
|
||||
protected final Set<XmlFile> myConfigFiles;
|
||||
private Class<T> myClass;
|
||||
private Project myProject;
|
||||
|
||||
/**
|
||||
* Using this method may result in a large memory usage, since it will keep all the DOM and PSI for all the config files
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public DomModelImpl(@NotNull T mergedModel, @NotNull Set<XmlFile> configFiles) {
|
||||
public DomModelImpl(T mergedModel, @NotNull Set<XmlFile> configFiles) {
|
||||
myMergedModel = DomUtil.getFileElement(mergedModel);
|
||||
myConfigFiles = configFiles;
|
||||
}
|
||||
|
||||
public DomModelImpl(@NotNull DomFileElement<T> mergedModel, @NotNull Set<XmlFile> configFiles) {
|
||||
public DomModelImpl(DomFileElement<T> mergedModel, @NotNull Set<XmlFile> configFiles) {
|
||||
myMergedModel = DomUtil.getFileElement(mergedModel);
|
||||
myConfigFiles = configFiles;
|
||||
}
|
||||
|
||||
public DomModelImpl(@NotNull Set<XmlFile> configFiles, Class<T> clazz, Project project) {
|
||||
myProject = project;
|
||||
myMergedModel = null;
|
||||
myConfigFiles = configFiles;
|
||||
myClass = clazz;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public T getMergedModel() {
|
||||
if (myMergedModel == null) {
|
||||
final DomManager domManager = DomManager.getDomManager(myProject);
|
||||
return domManager.createModelMerger().mergeModels(myClass, ContainerUtil.mapNotNull(myConfigFiles, new NullableFunction<XmlFile, T>() {
|
||||
public T fun(XmlFile xmlFile) {
|
||||
DomFileElement<T> fileElement = domManager.getFileElement(xmlFile, myClass);
|
||||
return fileElement == null ? null : fileElement.getRootElement();
|
||||
}
|
||||
}));
|
||||
}
|
||||
return myMergedModel.getRootElement();
|
||||
}
|
||||
|
||||
@@ -62,6 +80,13 @@ public class DomModelImpl<T extends DomElement> {
|
||||
|
||||
@NotNull
|
||||
public List<DomFileElement<T>> getRoots() {
|
||||
if (myMergedModel == null) {
|
||||
return ContainerUtil.mapNotNull(myConfigFiles, new NullableFunction<XmlFile, DomFileElement<T>>() {
|
||||
public DomFileElement<T> fun(XmlFile xmlFile) {
|
||||
return DomManager.getDomManager(xmlFile.getProject()).getFileElement(xmlFile, myClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
return myMergedModel instanceof MergedObject ? ((MergedObject) myMergedModel).getImplementations() : Collections.singletonList(myMergedModel);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user