From d9e79cbb53345b1475dcc10c3d19a146af770ad4 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Wed, 21 Apr 2010 12:31:58 +0400 Subject: [PATCH 01/36] Revert "Revert "Initial version of IRB/Rails consoles based on new LanguageConsole API"" This reverts commit fb28109271f6f23db4cb01484e97b33d8423d06c. Conflicts: platform/lang-impl/src/com/intellij/codeInsight/editorActions/BackspaceHandler.java --- .../execution/runners/AbstractConsoleRunnerWithHistory.java | 1 - 1 file changed, 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java index 47c217b0e4eb..b1c9c5de1898 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/AbstractConsoleRunnerWithHistory.java @@ -51,7 +51,6 @@ import java.awt.*; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; -import java.util.ArrayList; /** * @author oleg From c16110c85bcc8d1a303c9b107f3f51ed5f1aade3 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Fri, 28 May 2010 15:01:02 +0400 Subject: [PATCH 02/36] (commenter tests fixed): Revert "if line comment prefix is followed by a single space, uncomment line action deletes that space (PY-980)" This reverts commit 9177ef4358a81621df896946922f1360da5dd797. --- .../generation/CommentByLineCommentHandler.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java index 96f723a291d6..a3f2b6d1f104 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java @@ -464,15 +464,8 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler { boolean commented = CharArrayUtil.regionMatches(chars, startOffset, prefix) || (skipNewLine = prefix.endsWith(" ") && CharArrayUtil.regionMatches(chars, startOffset, prefix.trim() + "\n")); assert commented; - - int charsToDelete = skipNewLine ? prefix.trim().length() : prefix.length(); - int theEnd = endOffset > 0 ? endOffset : chars.length(); - // if there's exactly one space after line comment prefix and before the text that follows in the same line, delete the space too - if (startOffset + charsToDelete < theEnd-2 && chars.charAt(startOffset+charsToDelete) == ' ' && - chars.charAt(startOffset+charsToDelete+1) != ' ') { - charsToDelete++; - } - myDocument.deleteString(startOffset, startOffset + charsToDelete); + int position = 0;//text.indexOf(prefix); + myDocument.deleteString(position + startOffset , position + startOffset + (skipNewLine? prefix.trim().length():prefix.length())); return; } String text = myDocument.getCharsSequence().subSequence(startOffset, endOffset).toString(); From df24cfb0104d5884625ccaf0e1f9d0ae3f7a68d1 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Sun, 30 May 2010 16:29:38 +0400 Subject: [PATCH 03/36] 1. Deadlock in rvm sdks initialization fixed. 2. my shiny indian code was dropped! 3. SDKs api improved a bit --- .../impl/SdkConfigurationUtil.java | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java index 861611e4ff47..156074d7163e 100644 --- a/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java +++ b/platform/lang-impl/src/com/intellij/openapi/projectRoots/impl/SdkConfigurationUtil.java @@ -27,6 +27,7 @@ import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.SdkAdditionalData; import com.intellij.openapi.projectRoots.SdkType; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.ModuleRootManager; @@ -104,11 +105,30 @@ public class SdkConfigurationUtil { @Nullable public static Sdk setupSdk(final VirtualFile homeDir, final SdkType sdkType, final boolean silent) { + return setupSdk(homeDir, sdkType, silent, null, null); + } + + @Nullable + public static Sdk setupSdk(final VirtualFile homeDir, final SdkType sdkType, final boolean silent, + @Nullable final SdkAdditionalData additionalData, + @Nullable final String customSdkSuggestedName) { final Sdk[] sdks = ProjectJdkTable.getInstance().getAllJdks(); + final List sdksList = Arrays.asList(sdks); + final ProjectJdkImpl projectJdk; try { - final String sdkName = createUniqueSdkName(sdkType, homeDir.getPath(), Arrays.asList(sdks)); + final String sdkName = customSdkSuggestedName == null + ? createUniqueSdkName(sdkType, homeDir.getPath(), sdksList) + : createUniqueSdkName(customSdkSuggestedName, sdksList); projectJdk = new ProjectJdkImpl(sdkName, sdkType); + + if (additionalData != null) { + // additional initialization. + // E.g. some ruby sdks must be initialized before + // setupSdkPaths() method invocation + projectJdk.setSdkAdditionalData(additionalData); + } + projectJdk.setHomePath(homeDir.getPath()); sdkType.setupSdkPaths(projectJdk); } @@ -195,11 +215,14 @@ public class SdkConfigurationUtil { } public static String createUniqueSdkName(SdkType type, String home, final Collection sdks) { + return createUniqueSdkName(type.suggestSdkName(null, home), sdks); + } + + public static String createUniqueSdkName(final String suggestedName, final Collection sdks) { final Set names = new HashSet(); for (Sdk jdk : sdks) { names.add(jdk.getName()); } - final String suggestedName = type.suggestSdkName(null, home); String newSdkName = suggestedName; int i = 0; while (names.contains(newSdkName)) { From ef275977d877e19fee54632361a82ea360f3622a Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Sun, 30 May 2010 16:35:25 +0400 Subject: [PATCH 04/36] Restored for consistency: "if line comment prefix is followed by a single space, uncomment line action deletes that space (PY-980)"" This reverts commit 0de5b6dd19224ee3d3992e92a04a9df24aa4066f. --- .../generation/CommentByLineCommentHandler.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java index a3f2b6d1f104..96f723a291d6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/CommentByLineCommentHandler.java @@ -464,8 +464,15 @@ public class CommentByLineCommentHandler implements CodeInsightActionHandler { boolean commented = CharArrayUtil.regionMatches(chars, startOffset, prefix) || (skipNewLine = prefix.endsWith(" ") && CharArrayUtil.regionMatches(chars, startOffset, prefix.trim() + "\n")); assert commented; - int position = 0;//text.indexOf(prefix); - myDocument.deleteString(position + startOffset , position + startOffset + (skipNewLine? prefix.trim().length():prefix.length())); + + int charsToDelete = skipNewLine ? prefix.trim().length() : prefix.length(); + int theEnd = endOffset > 0 ? endOffset : chars.length(); + // if there's exactly one space after line comment prefix and before the text that follows in the same line, delete the space too + if (startOffset + charsToDelete < theEnd-2 && chars.charAt(startOffset+charsToDelete) == ' ' && + chars.charAt(startOffset+charsToDelete+1) != ' ') { + charsToDelete++; + } + myDocument.deleteString(startOffset, startOffset + charsToDelete); return; } String text = myDocument.getCharsSequence().subSequence(startOffset, endOffset).toString(); From c29260b7dcb736713aceebbc268f1fc09f9e0c5a Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Sun, 30 May 2010 18:46:09 +0400 Subject: [PATCH 05/36] diagnostics info for rake tasks reload script --- .../src/com/intellij/execution/ExecutionHelper.java | 2 +- .../com/intellij/openapi/util/text/StringUtil.java | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java b/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java index 142bbfc399b2..2afdc436b3b7 100644 --- a/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java @@ -88,7 +88,7 @@ public class ExecutionHelper { return; } for (final Exception exception : exceptionList) { - String[] messages = new String[]{exception.getMessage()}; + String[] messages = StringUtil.splitByLines(exception.getMessage()); if (messages.length == 0) messages = new String[]{"Unknown Error"}; errorTreeView.addMessage(MessageCategory.ERROR, messages, file, -1, -1, null); } diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 03d3965e4068..68c6ff4e95f9 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -34,11 +34,13 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.text.DateFormat; import java.util.*; +import java.util.regex.Pattern; //TeamCity inherits StringUtil: do not add private constructors!!! public class StringUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.text.StringUtil"); @NonNls private static final String VOWELS = "aeiouy"; + private static final Pattern EOL_SPLIT_PATTERN = Pattern.compile(" *(\r|\n|\r\n)+ *"); public static String replace(@NonNls @NotNull String text, @NonNls @NotNull String oldS, @NonNls @Nullable String newS) { return replace(text, oldS, newS, false); @@ -1600,4 +1602,14 @@ public class StringUtil { public static String tail(@NotNull String s, final int idx) { return idx >= s.length() ? "" : s.substring(idx, s.length()); } + + /** + * Splits string by lines. + * + * @param string String to split + * @return array of strings + */ + public static String[] splitByLines(final String string) { + return EOL_SPLIT_PATTERN.split(string); + } } From 3c7b47d76d451286af310d99c52942b5068d626b Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 1 Jun 2010 14:17:12 +0400 Subject: [PATCH 06/36] accept multiple comma-separated IDs in idea.load.plugins.id --- .../src/com/intellij/ide/plugins/PluginManager.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java index d71c281376b7..eaff330944c2 100644 --- a/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java +++ b/platform/platform-api/src/com/intellij/ide/plugins/PluginManager.java @@ -320,6 +320,7 @@ public class PluginManager { if (!shouldLoadPlugins()) return true; } + final List pluginIds = pluginId == null ? null : StringUtil.split(pluginId, ","); final boolean checkModuleDependencies = !ourAvailableModules.isEmpty() && !ourAvailableModules.contains("com.intellij.modules.all"); if (checkModuleDependencies && !hasModuleDependencies(descriptor)) { @@ -333,8 +334,8 @@ public class PluginManager { shouldLoad = loadPluginCategory.equals(descriptor.getCategory()); } else { - if (pluginId != null) { - shouldLoad = pluginId.equals(idString); + if (pluginIds != null) { + shouldLoad = pluginIds.contains(idString); if (!shouldLoad) { Map map = new HashMap(); for (final IdeaPluginDescriptor pluginDescriptor : loaded) { From 122e3a17e8b29a7cb1db9f9483da6f30e0363d2b Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 1 Jun 2010 15:59:58 +0400 Subject: [PATCH 07/36] support Ruby 1.9 named groups in regular expressions (RUBY-5822) --- .../lang/regexp/RegExpLanguageHost.java | 1 + .../intellij/lang/regexp/RegExpParser.java | 4 +- .../org/intellij/lang/regexp/RegExpTT.java | 9 +- .../org/intellij/lang/regexp/_RegExLexer.java | 361 ++++++++-------- .../intellij/lang/regexp/psi/RegExpGroup.java | 18 +- .../lang/regexp/psi/impl/RegExpGroupImpl.java | 59 +-- .../intellij/lang/regexp/regexp-lexer.flex | 17 +- .../regexp/validation/RegExpAnnotator.java | 392 +++++++++--------- 8 files changed, 458 insertions(+), 403 deletions(-) diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java index 748b20a324a2..37dcc6c527b1 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpLanguageHost.java @@ -24,4 +24,5 @@ public interface RegExpLanguageHost { boolean supportsPossessiveQuantifiers(); boolean supportsPythonNamedGroups(); boolean supportsPythonConditionalRefs(); + boolean supportsRubyNamedGroups(); } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java index 5ecaa0f0e28d..7b0f8a48dee9 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java @@ -346,10 +346,10 @@ public class RegExpParser implements PsiParser { } else if (type == RegExpTT.BACKREF) { builder.advanceLexer(); marker.done(RegExpElementTypes.BACKREF); - } else if (type == RegExpTT.PYTHON_NAMED_GROUP) { + } else if (type == RegExpTT.PYTHON_NAMED_GROUP || type == RegExpTT.RUBY_NAMED_GROUP || type == RegExpTT.RUBY_QUOTED_NAMED_GROUP) { builder.advanceLexer(); checkMatches(builder, RegExpTT.NAME, "Group name expected"); - checkMatches(builder, RegExpTT.GT, "Unclosed group name"); + checkMatches(builder, type == RegExpTT.RUBY_QUOTED_NAMED_GROUP ? RegExpTT.QUOTE : RegExpTT.GT, "Unclosed group name"); if (!parsePattern(builder)) { patternExpected(builder); } else { diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java index 519aa8652202..b60b7bd85e19 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpTT.java @@ -64,8 +64,10 @@ public interface RegExpTT { IElementType DOT = new RegExpElementType("DOT"); IElementType UNION = new RegExpElementType("UNION"); - // > in Python named group + // > in Python/Ruby named group IElementType GT = new RegExpElementType("GT"); + // ' in Ruby quoted named group + IElementType QUOTE = new RegExpElementType("QUOTE"); // "\b" | "\t" | "\f" | "\r" | "\n" IElementType CTRL_CHARACTER = new RegExpElementType("CTRL_CHARACTER"); @@ -107,6 +109,11 @@ public interface RegExpTT { // (?(id/name)yes-pattern|no-pattern) IElementType PYTHON_COND_REF = new RegExpElementType("PYTHON_COND_REF"); + // (?... + IElementType RUBY_NAMED_GROUP = new RegExpElementType("RUBY_NAMED_GROUP"); + + // (?'name'... + IElementType RUBY_QUOTED_NAMED_GROUP = new RegExpElementType("RUBY_QUOTED_NAMED_GROUP"); TokenSet KEYWORDS = TokenSet.create(DOT, STAR, QUEST, PLUS); diff --git a/RegExpSupport/src/org/intellij/lang/regexp/_RegExLexer.java b/RegExpSupport/src/org/intellij/lang/regexp/_RegExLexer.java index 33ad35eda461..18df5cb3c149 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/_RegExLexer.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/_RegExLexer.java @@ -1,12 +1,13 @@ -/* The following code was generated by JFlex 1.4.3 on 22.03.10 22:06 */ +/* The following code was generated by JFlex 1.4.3 on 01.06.10 15:51 */ /* It's an automatically generated code. Do not modify it. */ package org.intellij.lang.regexp; import com.intellij.lexer.FlexLexer; -import com.intellij.psi.tree.IElementType; -import java.util.LinkedList; import com.intellij.psi.StringEscapesTokenTypes; +import com.intellij.psi.tree.IElementType; + +import java.util.LinkedList; // IDEADEV-11055 @SuppressWarnings({ "ALL", "SameParameterValue", "WeakerAccess", "SameReturnValue", "RedundantThrows", "UnusedDeclaration", "UnusedDeclaration" }) @@ -14,8 +15,8 @@ import com.intellij.psi.StringEscapesTokenTypes; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 22.03.10 22:06 from the specification file - * C:/JetBrains/IDEA/tools/lexer/../../community/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex + * on 01.06.10 15:51 from the specification file + * C:/JetBrains/idea.branches/maia/tools/lexer/../../community/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex */ class _RegExLexer implements FlexLexer { /** initial size of the lookahead buffer */ @@ -23,15 +24,16 @@ class _RegExLexer implements FlexLexer { /** lexical states */ public static final int EMBRACED = 4; - public static final int PY_NAMED_GROUP = 16; - public static final int PY_NAMED_GROUP_REF = 18; + public static final int PY_NAMED_GROUP_REF = 20; public static final int QUOTED = 2; public static final int OPTIONS = 12; - public static final int PY_COND_REF = 20; + public static final int PY_COND_REF = 22; public static final int YYINITIAL = 0; + public static final int NAMED_GROUP = 16; public static final int CLASS2 = 8; public static final int CLASS1 = 6; public static final int COMMENT = 14; + public static final int QUOTED_NAMED_GROUP = 18; public static final int PROP = 10; /** @@ -42,15 +44,15 @@ class _RegExLexer implements FlexLexer { */ private static final int ZZ_LEXSTATE[] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, - 8, 8, 9, 9, 10, 10 + 8, 8, 9, 9, 10, 10, 11, 11 }; /** * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\10\0\2\52\1\13\1\0\1\52\1\61\22\0\1\45\1\56\1\0"+ - "\1\60\1\15\1\0\1\51\1\0\1\4\1\5\1\17\1\20\1\50"+ + "\10\0\2\52\1\13\1\0\1\52\1\62\22\0\1\45\1\56\1\0"+ + "\1\60\1\15\1\0\1\51\1\61\1\4\1\5\1\17\1\20\1\50"+ "\1\43\1\3\1\0\1\2\7\42\2\1\1\53\1\0\1\57\1\55"+ "\1\54\1\16\1\0\1\24\1\24\1\30\1\27\1\37\1\35\1\25"+ "\1\44\1\32\6\44\1\34\1\36\1\44\1\26\3\44\1\26\1\26"+ @@ -128,20 +130,20 @@ class _RegExLexer implements FlexLexer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\6\0\1\1\1\2\3\0\1\3\1\4\1\5\1\6"+ + "\6\0\1\1\1\2\4\0\1\3\1\4\1\5\1\6"+ "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16"+ "\1\17\1\20\1\21\1\22\1\23\1\3\1\24\1\25"+ "\1\26\1\27\1\30\1\31\1\32\1\33\1\34\1\3"+ "\1\35\1\36\1\35\1\37\1\40\1\1\1\41\1\42"+ "\1\2\1\43\1\44\1\45\1\46\1\47\1\50\1\51"+ - "\1\52\1\53\1\54\1\55\2\56\1\57\1\11\1\60"+ - "\1\61\1\62\1\63\1\64\1\65\1\0\1\66\1\67"+ - "\1\70\2\0\1\71\1\72\2\61\2\62\1\73\1\74"+ - "\1\75\1\76\1\0\1\71\1\61\1\77\2\62\1\100"+ - "\1\71\3\62\1\101"; + "\1\52\1\53\1\54\1\55\1\56\2\57\1\60\1\11"+ + "\1\61\1\62\1\63\1\64\1\65\1\66\1\0\1\67"+ + "\1\70\1\71\1\72\1\0\1\73\1\74\1\75\2\62"+ + "\2\63\1\76\1\77\1\100\1\101\1\0\1\74\1\62"+ + "\1\102\2\63\1\103\1\74\3\63\1\104"; private static int [] zzUnpackAction() { - int [] result = new int[97]; + int [] result = new int[100]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -166,22 +168,22 @@ class _RegExLexer implements FlexLexer { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\62\0\144\0\226\0\310\0\372\0\u012c\0\u015e"+ - "\0\u0190\0\u01c2\0\u01f4\0\u0226\0\u0226\0\u0258\0\u0226\0\u0226"+ - "\0\u028a\0\u02bc\0\u0226\0\u0226\0\u0226\0\u0226\0\u0226\0\u0226"+ - "\0\u0226\0\u0226\0\u0226\0\u0226\0\u02ee\0\u0226\0\u0320\0\u0226"+ - "\0\u0352\0\u0226\0\u0226\0\u0226\0\u0226\0\u0226\0\u0384\0\u0226"+ - "\0\u0226\0\u028a\0\u0226\0\u0226\0\u03b6\0\u03e8\0\u0226\0\u0226"+ - "\0\u0226\0\u041a\0\u0226\0\u0226\0\u044c\0\u047e\0\u0226\0\u0226"+ - "\0\u0226\0\u0226\0\u0226\0\u0226\0\u04b0\0\u0226\0\u0226\0\u0226"+ - "\0\u04e2\0\u0514\0\u0226\0\u0226\0\u0226\0\u0546\0\u0226\0\u0226"+ - "\0\u0226\0\u0578\0\u05aa\0\u05dc\0\u0226\0\u060e\0\u0640\0\u0672"+ - "\0\u06a4\0\u0226\0\u0226\0\u0226\0\u0226\0\u06d6\0\u0708\0\u0226"+ - "\0\u0226\0\u073a\0\u076c\0\u0226\0\u0226\0\u079e\0\u07d0\0\u0226"+ - "\0\u0226"; + "\0\0\0\63\0\146\0\231\0\314\0\377\0\u0132\0\u0165"+ + "\0\u0198\0\u01cb\0\u01fe\0\u0231\0\u0264\0\u0264\0\u0297\0\u0264"+ + "\0\u0264\0\u02ca\0\u02fd\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264"+ + "\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264\0\u0330\0\u0264\0\u0363"+ + "\0\u0264\0\u0396\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264\0\u03c9"+ + "\0\u0264\0\u0264\0\u02ca\0\u0264\0\u0264\0\u03fc\0\u042f\0\u0264"+ + "\0\u0264\0\u0264\0\u0264\0\u0462\0\u0264\0\u0264\0\u0495\0\u04c8"+ + "\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264\0\u0264\0\u04fb\0\u0264"+ + "\0\u0264\0\u0264\0\u052e\0\u0561\0\u0264\0\u0264\0\u0264\0\u0594"+ + "\0\u0264\0\u0264\0\u0264\0\u05c7\0\u05fa\0\u0264\0\u062d\0\u0264"+ + "\0\u0660\0\u0693\0\u06c6\0\u06f9\0\u0264\0\u0264\0\u0264\0\u0264"+ + "\0\u072c\0\u075f\0\u0264\0\u0264\0\u0792\0\u07c5\0\u0264\0\u0264"+ + "\0\u07f8\0\u082b\0\u0264\0\u0264"; private static int [] zzUnpackRowMap() { - int [] result = new int[97]; + int [] result = new int[100]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -204,46 +206,47 @@ class _RegExLexer implements FlexLexer { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\3\14\1\15\1\16\1\17\1\20\1\14\1\21\1\14"+ - "\1\22\1\23\1\24\1\25\1\26\1\27\1\30\1\31"+ - "\21\14\1\32\1\14\1\33\4\14\1\23\5\14\1\34"+ - "\1\23\12\14\1\35\1\0\46\14\1\36\2\37\4\36"+ - "\1\40\12\36\20\41\1\37\1\36\1\41\2\36\1\37"+ - "\1\42\11\36\11\43\1\44\1\43\1\0\46\43\6\14"+ - "\1\20\1\14\1\21\1\45\1\22\1\46\1\24\26\14"+ - "\1\32\5\14\1\47\1\46\6\14\1\46\6\50\1\51"+ - "\1\50\1\52\1\50\1\22\47\50\5\53\1\54\14\53"+ - "\20\55\1\53\1\56\1\55\6\53\1\57\6\53\13\10"+ - "\1\60\45\10\1\60\22\0\20\41\2\0\1\41\7\0"+ - "\1\61\5\0\5\53\1\54\14\53\20\41\2\53\1\41"+ - "\16\53\2\37\2\53\1\54\14\53\20\41\1\37\1\53"+ - "\1\41\2\53\1\37\12\53\100\0\1\62\54\0\1\63"+ - "\50\0\1\64\1\65\1\66\4\67\1\64\1\67\1\64"+ - "\1\67\1\70\6\67\2\71\2\72\2\73\1\74\1\75"+ - "\1\74\2\76\1\77\1\100\1\77\1\101\1\102\1\65"+ - "\1\67\1\77\1\70\4\64\1\70\6\64\1\70\37\0"+ - "\1\103\23\0\2\37\37\0\1\37\4\0\1\37\13\0"+ - "\2\41\17\0\21\41\1\0\1\41\1\0\2\41\63\0"+ - "\1\104\32\0\20\55\2\0\1\55\37\0\20\56\2\0"+ - "\1\56\21\0\1\105\27\0\1\106\16\0\2\107\1\110"+ - "\1\111\1\112\1\113\2\0\2\65\37\0\1\65\21\0"+ - "\1\114\37\0\1\114\17\0\62\115\1\116\2\117\20\116"+ - "\2\117\2\116\3\117\3\116\1\117\1\116\1\117\2\116"+ - "\1\117\17\116\1\120\2\121\20\120\2\121\2\120\3\121"+ - "\3\120\1\121\1\120\1\121\2\120\1\121\17\120\55\0"+ - "\1\122\1\0\1\123\57\0\1\124\1\125\3\0\5\126"+ - "\1\0\54\126\2\0\1\127\37\0\1\127\17\0\63\130"+ - "\2\131\20\130\2\131\2\130\3\131\3\130\1\131\1\130"+ - "\1\131\2\130\1\131\17\130\63\132\2\133\20\132\2\133"+ - "\2\132\3\133\3\132\1\133\1\132\1\133\2\132\1\133"+ - "\17\132\5\126\1\134\54\126\2\0\1\135\37\0\1\135"+ - "\17\0\63\136\2\137\20\136\2\137\2\136\3\137\3\136"+ - "\1\137\1\136\1\137\2\136\1\137\17\136\63\140\2\141"+ - "\20\140\2\141\2\140\3\141\3\140\1\141\1\140\1\141"+ - "\2\140\1\141\17\140"; + "\3\15\1\16\1\17\1\20\1\21\1\15\1\22\1\15"+ + "\1\23\1\24\1\25\1\26\1\27\1\30\1\31\1\32"+ + "\21\15\1\33\1\15\1\34\4\15\1\24\5\15\1\35"+ + "\1\15\1\24\12\15\1\36\1\0\47\15\1\37\2\40"+ + "\4\37\1\41\12\37\20\42\1\40\1\37\1\42\2\37"+ + "\1\40\1\43\12\37\11\44\1\45\1\44\1\0\47\44"+ + "\6\15\1\21\1\15\1\22\1\46\1\23\1\47\1\25"+ + "\26\15\1\33\5\15\1\50\1\47\7\15\1\47\6\51"+ + "\1\52\1\51\1\53\1\51\1\23\50\51\5\54\1\55"+ + "\14\54\20\56\1\54\1\57\1\56\6\54\1\60\7\54"+ + "\13\10\1\61\46\10\1\61\22\54\20\42\2\54\1\42"+ + "\7\54\1\62\30\54\20\42\2\54\1\42\14\54\1\63"+ + "\6\54\1\55\14\54\20\42\2\54\1\42\17\54\2\40"+ + "\2\54\1\55\14\54\20\42\1\40\1\54\1\42\2\54"+ + "\1\40\13\54\101\0\1\64\55\0\1\65\51\0\1\66"+ + "\1\67\1\70\4\71\1\66\1\71\1\66\1\71\1\72"+ + "\6\71\2\73\2\74\2\75\1\76\1\77\1\76\2\100"+ + "\1\101\1\102\1\101\1\103\1\104\1\67\1\71\1\101"+ + "\1\72\4\66\1\72\7\66\1\72\37\0\1\105\24\0"+ + "\2\40\37\0\1\40\4\0\1\40\14\0\2\42\17\0"+ + "\21\42\1\0\1\42\1\0\2\42\64\0\1\106\33\0"+ + "\20\56\2\0\1\56\40\0\20\57\2\0\1\57\22\0"+ + "\1\107\27\0\1\110\16\0\2\111\1\112\1\113\1\114"+ + "\1\115\1\116\2\0\2\67\37\0\1\67\22\0\1\117"+ + "\37\0\1\117\20\0\63\120\1\121\2\122\20\121\2\122"+ + "\2\121\3\122\3\121\1\122\1\121\1\122\2\121\1\122"+ + "\20\121\1\123\2\124\20\123\2\124\2\123\3\124\3\123"+ + "\1\124\1\123\1\124\2\123\1\124\20\123\55\0\1\125"+ + "\1\0\1\126\60\0\1\127\1\130\4\0\5\131\1\0"+ + "\55\131\2\0\1\132\37\0\1\132\20\0\64\133\2\134"+ + "\20\133\2\134\2\133\3\134\3\133\1\134\1\133\1\134"+ + "\2\133\1\134\20\133\64\135\2\136\20\135\2\136\2\135"+ + "\3\136\3\135\1\136\1\135\1\136\2\135\1\136\20\135"+ + "\5\131\1\137\55\131\2\0\1\140\37\0\1\140\20\0"+ + "\64\141\2\142\20\141\2\142\2\141\3\142\3\141\1\142"+ + "\1\141\1\142\2\141\1\142\20\141\64\143\2\144\20\143"+ + "\2\144\2\143\3\144\3\143\1\144\1\143\1\144\2\143"+ + "\1\144\20\143"; private static int [] zzUnpackTrans() { - int [] result = new int[2050]; + int [] result = new int[2142]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -284,15 +287,15 @@ class _RegExLexer implements FlexLexer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\6\0\2\1\3\0\2\11\1\1\2\11\2\1\12\11"+ + "\6\0\2\1\4\0\2\11\1\1\2\11\2\1\12\11"+ "\1\1\1\11\1\1\1\11\1\1\5\11\1\1\2\11"+ - "\1\1\2\11\2\1\3\11\1\1\2\11\2\1\6\11"+ - "\1\1\3\11\2\1\3\11\1\0\3\11\2\0\1\1"+ - "\1\11\4\1\4\11\1\0\1\1\2\11\2\1\2\11"+ - "\2\1\2\11"; + "\1\1\2\11\2\1\4\11\1\1\2\11\2\1\6\11"+ + "\1\1\3\11\2\1\3\11\1\0\3\11\1\1\1\0"+ + "\1\11\1\1\1\11\4\1\4\11\1\0\1\1\2\11"+ + "\2\1\2\11\2\1\2\11"; private static int [] zzUnpackAttribute() { - int [] result = new int[97]; + int [] result = new int[100]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -648,257 +651,269 @@ class _RegExLexer implements FlexLexer { case 7: { if (yystate() != CLASS2) yypushstate(EMBRACED); return RegExpTT.LBRACE; } - case 66: break; + case 69: break; case 6: { return RegExpTT.GROUP_END; } - case 67: break; - case 37: + case 70: break; + case 38: // lookahead expression with fixed base length zzMarkedPos = zzStartRead + 1; { yypushstate(CLASS1); return RegExpTT.CLASS_BEGIN; } - case 68: break; + case 71: break; case 14: { return RegExpTT.STAR; } - case 69: break; - case 41: + case 72: break; + case 42: { return RegExpTT.ESC_CHARACTER; } - case 70: break; + case 73: break; case 28: { return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.ESC_CHARACTER; } - case 71: break; - case 42: + case 74: break; + case 43: { return commentMode ? RegExpTT.CHARACTER : RegExpTT.REDUNDANT_ESCAPE; } - case 72: break; - case 38: + case 75: break; + case 39: { return RegExpTT.REDUNDANT_ESCAPE; } - case 73: break; + case 76: break; case 24: { return RegExpTT.COMMA; } - case 74: break; - case 61: + case 77: break; + case 58: + { yybegin(NAMED_GROUP); return RegExpTT.RUBY_NAMED_GROUP; + } + case 78: break; + case 64: { return RegExpTT.POS_LOOKBEHIND; } - case 75: break; - case 40: + case 79: break; + case 41: { return RegExpTT.BAD_OCT_VALUE; } - case 76: break; + case 80: break; case 10: { return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.CTRL_CHARACTER; } - case 77: break; + case 81: break; case 30: { yypopstate(); yypushstate(EMBRACED); return RegExpTT.LBRACE; } - case 78: break; - case 50: + case 82: break; + case 51: { return StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN; } - case 79: break; - case 62: + case 83: break; + case 65: { return RegExpTT.NEG_LOOKBEHIND; } - case 80: break; - case 65: + case 84: break; + case 68: { return RegExpTT.UNICODE_CHAR; } - case 81: break; - case 58: + case 85: break; + case 61: { if (xmlSchemaMode) { yypushback(1); return RegExpTT.CHAR_CLASS; } else return RegExpTT.CTRL; } - case 82: break; - case 36: + case 86: break; + case 37: { yybegin(OPTIONS); return RegExpTT.SET_OPTIONS; } - case 83: break; + case 87: break; case 12: { return RegExpTT.DOLLAR; } - case 84: break; - case 51: + case 88: break; + case 52: { yypopstate(); return RegExpTT.QUOTE_END; } - case 85: break; - case 55: + case 89: break; + case 56: { return RegExpTT.POS_LOOKAHEAD; } - case 86: break; + case 90: break; case 22: { yypopstate(); return RegExpTT.RBRACE; } - case 87: break; + case 91: break; case 3: { return RegExpTT.CHARACTER; } - case 88: break; - case 56: + case 92: break; + case 57: { return RegExpTT.NEG_LOOKAHEAD; } - case 89: break; - case 43: + case 93: break; + case 44: { return RegExpTT.ESC_CTRL_CHARACTER; } - case 90: break; + case 94: break; case 23: { return RegExpTT.NAME; } - case 91: break; - case 52: + case 95: break; + case 53: { return RegExpTT.ANDAND; } - case 92: break; + case 96: break; case 13: { return RegExpTT.QUEST; } - case 93: break; - case 45: + case 97: break; + case 46: { return RegExpTT.CHAR_CLASS; } - case 94: break; + case 98: break; case 17: { return RegExpTT.MINUS; } - case 95: break; - case 64: + case 99: break; + case 67: { return RegExpTT.COMMENT; } - case 96: break; - case 39: + case 100: break; + case 40: { return yystate() != CLASS2 ? RegExpTT.BACKREF : RegExpTT.ESC_CHARACTER; } - case 97: break; + case 101: break; case 16: { return RegExpTT.UNION; } - case 98: break; - case 46: + case 102: break; + case 47: { if (xmlSchemaMode) return RegExpTT.CHAR_CLASS; else return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN; } - case 99: break; - case 57: + case 103: break; + case 60: { return RegExpTT.OCT_CHAR; } - case 100: break; + case 104: break; case 4: { return RegExpTT.DOT; } - case 101: break; + case 105: break; case 32: { yybegin(YYINITIAL); return RegExpTT.GROUP_END; } - case 102: break; + case 106: break; case 21: { return RegExpTT.NUMBER; } - case 103: break; + case 107: break; case 35: { yybegin(YYINITIAL); return RegExpTT.GT; } - case 104: break; - case 53: + case 108: break; + case 59: + { yybegin(QUOTED_NAMED_GROUP); return RegExpTT.RUBY_QUOTED_NAMED_GROUP; + } + case 109: break; + case 54: { yybegin(PY_COND_REF); return RegExpTT.PYTHON_COND_REF; } - case 105: break; - case 47: + case 110: break; + case 48: { yypushstate(PROP); return RegExpTT.PROPERTY; } - case 106: break; + case 111: break; case 18: { return commentMode ? com.intellij.psi.TokenType.WHITE_SPACE : RegExpTT.CHARACTER; } - case 107: break; + case 112: break; case 33: { handleOptions(); return RegExpTT.OPTIONS_OFF; } - case 108: break; + case 113: break; case 34: { yybegin(YYINITIAL); return RegExpTT.COLON; } - case 109: break; + case 114: break; case 25: { assert false : yytext(); } - case 110: break; - case 59: + case 115: break; + case 62: { yybegin(PY_NAMED_GROUP_REF); return RegExpTT.PYTHON_NAMED_GROUP_REF; } - case 111: break; + case 116: break; case 27: { yypopstate(); return RegExpTT.CLASS_END; } - case 112: break; + case 117: break; case 11: { return RegExpTT.CARET; } - case 113: break; + case 118: break; case 1: { handleOptions(); return RegExpTT.OPTIONS_ON; } - case 114: break; + case 119: break; case 29: { yypopstate(); yypushback(1); } - case 115: break; - case 44: + case 120: break; + case 45: { return yystate() != CLASS2 ? RegExpTT.BOUNDARY : RegExpTT.ESC_CHARACTER; } - case 116: break; + case 121: break; + case 63: + { yybegin(NAMED_GROUP); return RegExpTT.PYTHON_NAMED_GROUP; + } + case 122: break; case 19: { if (commentMode) { yypushstate(COMMENT); return RegExpTT.COMMENT; } else return RegExpTT.CHARACTER; } - case 117: break; - case 63: + case 123: break; + case 66: { return RegExpTT.HEX_CHAR; } - case 118: break; - case 60: - { yybegin(PY_NAMED_GROUP); return RegExpTT.PYTHON_NAMED_GROUP; - } - case 119: break; + case 124: break; case 5: { return RegExpTT.GROUP_BEGIN; } - case 120: break; + case 125: break; case 8: { yypushstate(CLASS2); return RegExpTT.CLASS_BEGIN; } - case 121: break; - case 54: + case 126: break; + case 55: { return RegExpTT.NON_CAPT_GROUP; } - case 122: break; + case 127: break; case 9: { return StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN; } - case 123: break; - case 49: + case 128: break; + case 36: + { yybegin(YYINITIAL); return RegExpTT.QUOTE; + } + case 129: break; + case 50: { return RegExpTT.BAD_HEX_VALUE; } - case 124: break; + case 130: break; case 2: { yypopstate(); return RegExpTT.COMMENT; } - case 125: break; - case 48: + case 131: break; + case 49: { yypushstate(QUOTED); return RegExpTT.QUOTE_BEGIN; } - case 126: break; + case 132: break; case 26: { yybegin(CLASS2); return RegExpTT.CHARACTER; } - case 127: break; + case 133: break; case 15: { return RegExpTT.PLUS; } - case 128: break; + case 134: break; case 20: { if (allowDanglingMetacharacters) { yypopstate(); yypushback(1); @@ -906,11 +921,11 @@ class _RegExLexer implements FlexLexer { return RegExpTT.BAD_CHARACTER; } } - case 129: break; + case 135: break; case 31: { yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER; } - case 130: break; + case 136: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true; diff --git a/RegExpSupport/src/org/intellij/lang/regexp/psi/RegExpGroup.java b/RegExpSupport/src/org/intellij/lang/regexp/psi/RegExpGroup.java index b05b83944aff..d1afd4e05b79 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/psi/RegExpGroup.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/psi/RegExpGroup.java @@ -18,15 +18,17 @@ package org.intellij.lang.regexp.psi; import org.jetbrains.annotations.Nullable; public interface RegExpGroup extends RegExpAtom { - boolean isCapturing(); - - boolean isSimple(); + boolean isCapturing(); - @Nullable - RegExpPattern getPattern(); + boolean isSimple(); - boolean isPythonNamedGroup(); + @Nullable + RegExpPattern getPattern(); - @Nullable - String getGroupName(); + boolean isPythonNamedGroup(); + + boolean isRubyNamedGroup(); + + @Nullable + String getGroupName(); } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/psi/impl/RegExpGroupImpl.java b/RegExpSupport/src/org/intellij/lang/regexp/psi/impl/RegExpGroupImpl.java index cc4d0e230983..b24669757917 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/psi/impl/RegExpGroupImpl.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/psi/impl/RegExpGroupImpl.java @@ -24,38 +24,43 @@ import org.intellij.lang.regexp.psi.RegExpGroup; import org.intellij.lang.regexp.psi.RegExpPattern; public class RegExpGroupImpl extends RegExpElementImpl implements RegExpGroup { - public RegExpGroupImpl(ASTNode astNode) { - super(astNode); - } + public RegExpGroupImpl(ASTNode astNode) { + super(astNode); + } - public void accept(RegExpElementVisitor visitor) { - visitor.visitRegExpGroup(this); - } + public void accept(RegExpElementVisitor visitor) { + visitor.visitRegExpGroup(this); + } - public boolean isCapturing() { - final ASTNode node = getNode().getFirstChildNode(); - return node != null && node.getElementType() == RegExpTT.GROUP_BEGIN; - } + public boolean isCapturing() { + final ASTNode node = getNode().getFirstChildNode(); + return node != null && node.getElementType() == RegExpTT.GROUP_BEGIN; + } - public boolean isSimple() { - final ASTNode node = getNode().getFirstChildNode(); - return node != null && (node.getElementType() == RegExpTT.GROUP_BEGIN || node.getElementType() == RegExpTT.NON_CAPT_GROUP); - } + public boolean isSimple() { + final ASTNode node = getNode().getFirstChildNode(); + return node != null && (node.getElementType() == RegExpTT.GROUP_BEGIN || node.getElementType() == RegExpTT.NON_CAPT_GROUP); + } - public RegExpPattern getPattern() { - final ASTNode node = getNode().findChildByType(RegExpElementTypes.PATTERN); - return node != null ? (RegExpPattern)node.getPsi() : null; - } + public RegExpPattern getPattern() { + final ASTNode node = getNode().findChildByType(RegExpElementTypes.PATTERN); + return node != null ? (RegExpPattern)node.getPsi() : null; + } - public boolean isPythonNamedGroup() { - return getNode().findChildByType(RegExpTT.PYTHON_NAMED_GROUP) != null; - } + public boolean isPythonNamedGroup() { + return getNode().findChildByType(RegExpTT.PYTHON_NAMED_GROUP) != null; + } - public String getGroupName() { - if (!isPythonNamedGroup()) { - return null; - } - final ASTNode nameNode = getNode().findChildByType(RegExpTT.NAME); - return nameNode != null ? nameNode.getText() : null; + public boolean isRubyNamedGroup() { + return getNode().findChildByType(RegExpTT.RUBY_NAMED_GROUP) != null || + getNode().findChildByType(RegExpTT.RUBY_QUOTED_NAMED_GROUP) != null; + } + + public String getGroupName() { + if (!isPythonNamedGroup()) { + return null; } + final ASTNode nameNode = getNode().findChildByType(RegExpTT.NAME); + return nameNode != null ? nameNode.getText() : null; + } } diff --git a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex index ab5384b253e0..5269feebd791 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex +++ b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex @@ -62,7 +62,8 @@ import com.intellij.psi.StringEscapesTokenTypes; %state PROP %xstate OPTIONS %xstate COMMENT -%xstate PY_NAMED_GROUP +%xstate NAMED_GROUP +%xstate QUOTED_NAMED_GROUP %xstate PY_NAMED_GROUP_REF %xstate PY_COND_REF @@ -208,10 +209,13 @@ HEX_CHAR=[0-9a-fA-F] "(?<=" { return RegExpTT.POS_LOOKBEHIND; } "(? { + { [:letter:]([:letter:]|_|[:digit:])* { return RegExpTT.NAME; } ">" { yybegin(YYINITIAL); return RegExpTT.GT; } + {ANY} { yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER; } +} + + { + [:letter:]([:letter:]|_|[:digit:])* { return RegExpTT.NAME; } + "'" { yybegin(YYINITIAL); return RegExpTT.QUOTE; } + {ANY} { yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER; } } { diff --git a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java index 546c6373c28c..930dc971c443 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java @@ -34,144 +34,152 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public final class RegExpAnnotator extends RegExpElementVisitor implements Annotator { - private AnnotationHolder myHolder; + private AnnotationHolder myHolder; - public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) { - assert myHolder == null : "unsupported concurrent annotator invocation"; - try { - myHolder = holder; - psiElement.accept(this); - } finally { - myHolder = null; - } + public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) { + assert myHolder == null : "unsupported concurrent annotator invocation"; + try { + myHolder = holder; + psiElement.accept(this); } + finally { + myHolder = null; + } + } - public void visitRegExpCharRange(RegExpCharRange range) { - final RegExpCharRange.Endpoint from = range.getFrom(); - final RegExpCharRange.Endpoint to = range.getTo(); - final boolean a = from instanceof RegExpChar; - final boolean b = to instanceof RegExpChar; - if (a && b) { - final Character t = ((RegExpChar)to).getValue(); - final Character f = ((RegExpChar)from).getValue(); - if (t != null && f != null) { - if (t < f) { - myHolder.createErrorAnnotation(range, "Illegal character range (to < from)"); - } else if (t == f) { - myHolder.createWarningAnnotation(range, "Redundant character range"); - } + public void visitRegExpCharRange(RegExpCharRange range) { + final RegExpCharRange.Endpoint from = range.getFrom(); + final RegExpCharRange.Endpoint to = range.getTo(); + final boolean a = from instanceof RegExpChar; + final boolean b = to instanceof RegExpChar; + if (a && b) { + final Character t = ((RegExpChar)to).getValue(); + final Character f = ((RegExpChar)from).getValue(); + if (t != null && f != null) { + if (t < f) { + myHolder.createErrorAnnotation(range, "Illegal character range (to < from)"); + } + else if (t == f) { + myHolder.createWarningAnnotation(range, "Redundant character range"); + } + } + } + else if (a != b) { + myHolder.createErrorAnnotation(range, "Character class (e.g. '\\\\w') may not be used inside character range"); + } + else if (from.getText().equals(to.getText())) { + myHolder.createWarningAnnotation(range, "Redundant character range"); + } + } + + public void visitRegExpChar(final RegExpChar ch) { + final Character value = ch.getValue(); + if (value == null) { + switch (ch.getType()) { + case CHAR: + myHolder.createErrorAnnotation(ch, "Illegal/unsupported escape sequence"); + break; + case HEX: + myHolder.createErrorAnnotation(ch, "Illegal hexadecimal escape sequence"); + break; + case OCT: + myHolder.createErrorAnnotation(ch, "Illegal octal escape sequence"); + break; + case UNICODE: + myHolder.createErrorAnnotation(ch, "Illegal unicode escape sequence"); + break; + case INVALID: + // produces a parser error. already handled by IDEA and possibly suppressed by IntelliLang + break; + } + } + else { + final String text = ch.getUnescapedText(); + if (text.startsWith("\\") && isRedundantEscape(ch, text)) { + final ASTNode astNode = ch.getNode().getFirstChildNode(); + if (astNode != null && astNode.getElementType() == RegExpTT.REDUNDANT_ESCAPE) { + final Annotation a = myHolder.createInformationAnnotation(ch, "Redundant character escape"); + registerFix(a, new RemoveRedundantEscapeAction(ch)); + } + } + } + } + + private static boolean isRedundantEscape(RegExpChar ch, String text) { + if (text.length() <= 1) return false; + RegExpLanguageHost host = findRegExpHost(ch); + if (host != null) { + final char c = text.charAt(1); + final boolean needsEscaping = host.characterNeedsEscaping(c); + return !needsEscaping; + } + else { + return !("\\]".equals(text) || "\\}".equals(text)); + } + } + + @Nullable + private static RegExpLanguageHost findRegExpHost(PsiElement element) { + PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element); + if (host instanceof RegExpLanguageHost) { + return (RegExpLanguageHost)host; + } + return null; + } + + public void visitRegExpProperty(RegExpProperty property) { + final ASTNode category = property.getCategoryNode(); + if (category != null && !RegExpPropertyImpl.isValidCategory(category.getText())) { + final Annotation a = myHolder.createErrorAnnotation(category, "Unknown character category"); + if (a != null) { + // IDEA-9381 + a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + } + } + } + + public void visitRegExpBackref(final RegExpBackref backref) { + final RegExpGroup group = backref.resolve(); + if (group == null) { + final Annotation a = myHolder.createErrorAnnotation(backref, "Unresolved backreference"); + if (a != null) { + // IDEA-9381 + a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + } + } + else if (PsiTreeUtil.isAncestor(group, backref, true)) { + myHolder.createWarningAnnotation(backref, "Backreference is nested into the capturing group it refers to"); + } + } + + public void visitRegExpGroup(RegExpGroup group) { + final RegExpPattern pattern = group.getPattern(); + if (pattern != null) { + final RegExpBranch[] branches = pattern.getBranches(); + if (isEmpty(branches)) { + // catches "()" as well as "(|)" + myHolder.createWarningAnnotation(group, "Empty group"); + } + else if (branches.length == 1) { + final RegExpAtom[] atoms = branches[0].getAtoms(); + if (atoms.length == 1 && atoms[0] instanceof RegExpGroup) { + if (group.isSimple()) { + final RegExpGroup innerGroup = (RegExpGroup)atoms[0]; + if (group.isCapturing() == innerGroup.isCapturing()) { + myHolder.createWarningAnnotation(group, "Redundant group nesting"); } - } else if (a != b) { - myHolder.createErrorAnnotation(range, "Character class (e.g. '\\\\w') may not be used inside character range"); - } else if (from.getText().equals(to.getText())) { - myHolder.createWarningAnnotation(range, "Redundant character range"); + } } + } } - - public void visitRegExpChar(final RegExpChar ch) { - final Character value = ch.getValue(); - if (value == null) { - switch (ch.getType()) { - case CHAR: - myHolder.createErrorAnnotation(ch, "Illegal/unsupported escape sequence"); - break; - case HEX: - myHolder.createErrorAnnotation(ch, "Illegal hexadecimal escape sequence"); - break; - case OCT: - myHolder.createErrorAnnotation(ch, "Illegal octal escape sequence"); - break; - case UNICODE: - myHolder.createErrorAnnotation(ch, "Illegal unicode escape sequence"); - break; - case INVALID: - // produces a parser error. already handled by IDEA and possibly suppressed by IntelliLang - break; - } - } else { - final String text = ch.getUnescapedText(); - if (text.startsWith("\\") && isRedundantEscape(ch, text)) { - final ASTNode astNode = ch.getNode().getFirstChildNode(); - if (astNode != null && astNode.getElementType() == RegExpTT.REDUNDANT_ESCAPE) { - final Annotation a = myHolder.createInformationAnnotation(ch, "Redundant character escape"); - registerFix(a, new RemoveRedundantEscapeAction(ch)); - } - } - } - } - - private static boolean isRedundantEscape(RegExpChar ch, String text) { - if (text.length() <= 1) return false; - RegExpLanguageHost host = findRegExpHost(ch); - if (host != null) { - final char c = text.charAt(1); - final boolean needsEscaping = host.characterNeedsEscaping(c); - return !needsEscaping; - } - else { - return!("\\]".equals(text) || "\\}".equals(text)); - } - } - - @Nullable - private static RegExpLanguageHost findRegExpHost(PsiElement element) { - PsiLanguageInjectionHost host = InjectedLanguageManager.getInstance(element.getProject()).getInjectionHost(element); - if (host instanceof RegExpLanguageHost) { - return (RegExpLanguageHost) host; - } - return null; - } - - public void visitRegExpProperty(RegExpProperty property) { - final ASTNode category = property.getCategoryNode(); - if (category != null && !RegExpPropertyImpl.isValidCategory(category.getText())) { - final Annotation a = myHolder.createErrorAnnotation(category, "Unknown character category"); - if (a != null) { - // IDEA-9381 - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); - } - } - } - - public void visitRegExpBackref(final RegExpBackref backref) { - final RegExpGroup group = backref.resolve(); - if (group == null) { - final Annotation a = myHolder.createErrorAnnotation(backref, "Unresolved backreference"); - if (a != null) { - // IDEA-9381 - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); - } - } else if (PsiTreeUtil.isAncestor(group, backref, true)) { - myHolder.createWarningAnnotation(backref, "Backreference is nested into the capturing group it refers to"); - } - } - - public void visitRegExpGroup(RegExpGroup group) { - final RegExpPattern pattern = group.getPattern(); - if (pattern != null) { - final RegExpBranch[] branches = pattern.getBranches(); - if (isEmpty(branches)) { - // catches "()" as well as "(|)" - myHolder.createWarningAnnotation(group, "Empty group"); - } else if (branches.length == 1) { - final RegExpAtom[] atoms = branches[0].getAtoms(); - if (atoms.length == 1 && atoms[0] instanceof RegExpGroup) { - if (group.isSimple()) { - final RegExpGroup innerGroup = (RegExpGroup)atoms[0]; - if (group.isCapturing() == innerGroup.isCapturing()) { - myHolder.createWarningAnnotation(group, "Redundant group nesting"); - } - } - } - } - } - if (group.isPythonNamedGroup()) { - RegExpLanguageHost host = findRegExpHost(group); - if (host == null || !host.supportsPythonNamedGroups()) { - myHolder.createErrorAnnotation(group, "This named group syntax is not supported"); - } - } + if (group.isPythonNamedGroup() || group.isRubyNamedGroup()) { + RegExpLanguageHost host = findRegExpHost(group); + if (host == null || (group.isPythonNamedGroup() && !host.supportsPythonNamedGroups()) || + (group.isRubyNamedGroup() && !host.supportsRubyNamedGroups())) { + myHolder.createErrorAnnotation(group, "This named group syntax is not supported"); + } } + } @Override public void visitRegExpPyNamedGroupRef(RegExpPyNamedGroupRef groupRef) { @@ -182,85 +190,91 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot } final RegExpGroup group = groupRef.resolve(); if (group == null) { - final Annotation a = myHolder.createErrorAnnotation(groupRef, "Unresolved backreference"); - if (a != null) { - // IDEA-9381 - a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); - } - } else if (PsiTreeUtil.isAncestor(group, groupRef, true)) { + final Annotation a = myHolder.createErrorAnnotation(groupRef, "Unresolved backreference"); + if (a != null) { + // IDEA-9381 + a.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL); + } + } + else if (PsiTreeUtil.isAncestor(group, groupRef, true)) { myHolder.createWarningAnnotation(groupRef, "Group reference is nested into the named group it refers to"); } } @Override - public void visitComment(PsiComment comment) { - if (comment.getText().startsWith("(?#")) { - RegExpLanguageHost host = findRegExpHost(comment); - if (host == null || !host.supportsPerl5EmbeddedComments()) { - myHolder.createErrorAnnotation(comment, "Embedded comments are not supported"); - } - } + public void visitComment(PsiComment comment) { + if (comment.getText().startsWith("(?#")) { + RegExpLanguageHost host = findRegExpHost(comment); + if (host == null || !host.supportsPerl5EmbeddedComments()) { + myHolder.createErrorAnnotation(comment, "Embedded comments are not supported"); + } } + } @Override public void visitRegExpPyCondRef(RegExpPyCondRef condRef) { RegExpLanguageHost host = findRegExpHost(condRef); if (host == null || !host.supportsPythonConditionalRefs()) { - myHolder.createErrorAnnotation(condRef, "Conditional references are not supported"); + myHolder.createErrorAnnotation(condRef, "Conditional references are not supported"); } } private static boolean isEmpty(RegExpBranch[] branches) { - for (RegExpBranch branch : branches) { - if (branch.getAtoms().length > 0) { - return false; - } - } - return true; + for (RegExpBranch branch : branches) { + if (branch.getAtoms().length > 0) { + return false; + } } + return true; + } - public void visitRegExpQuantifier(RegExpQuantifier quantifier) { - final RegExpQuantifier.Count count = quantifier.getCount(); - if (!(count instanceof RegExpQuantifier.SimpleCount)) { - final int min = count.getMin(); - final int max = count.getMax(); - if (max < min) { - myHolder.createErrorAnnotation(quantifier, "Illegal repetition range"); - } else if (max == min) { - if (max == 1) { // TODO: is this safe when reluctant or possesive modifier is present? - final Annotation a = myHolder.createInformationAnnotation(quantifier, "Single repetition"); - registerFix(a, new SimplifyQuantifierAction(quantifier, null)); - } else { - final ASTNode node = quantifier.getNode(); - if (node.findChildByType(RegExpTT.COMMA) != null) { - final Annotation a = myHolder.createInformationAnnotation(quantifier, "Fixed repetition range"); - registerFix(a, new SimplifyQuantifierAction(quantifier, "{" + max + "}")); - } - } - } else if (min == 0 && max == 1) { - final Annotation a = myHolder.createInformationAnnotation(quantifier, "Repetition range replaceable by '?'"); - registerFix(a, new SimplifyQuantifierAction(quantifier, "?")); - } else if (min == 0 && max == Integer.MAX_VALUE) { - final Annotation a = myHolder.createInformationAnnotation(quantifier, "Repetition range replaceable by '*'"); - registerFix(a, new SimplifyQuantifierAction(quantifier, "*")); - } else if (min == 1 && max == Integer.MAX_VALUE) { - final Annotation a = myHolder.createInformationAnnotation(quantifier, "Repetition range replaceable by '+'"); - registerFix(a, new SimplifyQuantifierAction(quantifier, "+")); - } + public void visitRegExpQuantifier(RegExpQuantifier quantifier) { + final RegExpQuantifier.Count count = quantifier.getCount(); + if (!(count instanceof RegExpQuantifier.SimpleCount)) { + final int min = count.getMin(); + final int max = count.getMax(); + if (max < min) { + myHolder.createErrorAnnotation(quantifier, "Illegal repetition range"); + } + else if (max == min) { + if (max == 1) { // TODO: is this safe when reluctant or possesive modifier is present? + final Annotation a = myHolder.createInformationAnnotation(quantifier, "Single repetition"); + registerFix(a, new SimplifyQuantifierAction(quantifier, null)); } - if (quantifier.getType() == RegExpQuantifier.Type.POSSESSIVE) { - RegExpLanguageHost host = findRegExpHost(quantifier); - if (host != null && !host.supportsPossessiveQuantifiers()) { - myHolder.createErrorAnnotation(quantifier, "Nested quantifier in regexp"); - } + else { + final ASTNode node = quantifier.getNode(); + if (node.findChildByType(RegExpTT.COMMA) != null) { + final Annotation a = myHolder.createInformationAnnotation(quantifier, "Fixed repetition range"); + registerFix(a, new SimplifyQuantifierAction(quantifier, "{" + max + "}")); + } } + } + else if (min == 0 && max == 1) { + final Annotation a = myHolder.createInformationAnnotation(quantifier, "Repetition range replaceable by '?'"); + registerFix(a, new SimplifyQuantifierAction(quantifier, "?")); + } + else if (min == 0 && max == Integer.MAX_VALUE) { + final Annotation a = myHolder.createInformationAnnotation(quantifier, "Repetition range replaceable by '*'"); + registerFix(a, new SimplifyQuantifierAction(quantifier, "*")); + } + else if (min == 1 && max == Integer.MAX_VALUE) { + final Annotation a = myHolder.createInformationAnnotation(quantifier, "Repetition range replaceable by '+'"); + registerFix(a, new SimplifyQuantifierAction(quantifier, "+")); + } } + if (quantifier.getType() == RegExpQuantifier.Type.POSSESSIVE) { + RegExpLanguageHost host = findRegExpHost(quantifier); + if (host != null && !host.supportsPossessiveQuantifiers()) { + myHolder.createErrorAnnotation(quantifier, "Nested quantifier in regexp"); + } + } + } - private static void registerFix(Annotation a, IntentionAction action) { - if (a != null) { - // IDEA-9381 - a.registerFix(action); - } + private static void registerFix(Annotation a, IntentionAction action) { + if (a != null) { + // IDEA-9381 + a.registerFix(action); } + } } \ No newline at end of file From d5ed7b2b532a2b3ae15b39f164ca780b76640586 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 1 Jun 2010 16:28:10 +0400 Subject: [PATCH 08/36] Ruby 1.9 allows to omit minimum number in quantifier (RUBY-5785) --- .../intellij/lang/regexp/RegExpParser.java | 779 +++++++++--------- 1 file changed, 412 insertions(+), 367 deletions(-) diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java index 7b0f8a48dee9..d5d576b36df1 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java @@ -23,417 +23,462 @@ import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -@SuppressWarnings({ "RedundantIfStatement" }) +@SuppressWarnings({"RedundantIfStatement"}) public class RegExpParser implements PsiParser { private boolean myAllowDanglingMetacharacters; + private boolean myAllowOmitNumbersInQuantifiers; public void setAllowDanglingMetacharacters(boolean allowDanglingMetacharacters) { myAllowDanglingMetacharacters = allowDanglingMetacharacters; } - @NotNull - public ASTNode parse(IElementType root, PsiBuilder builder) { + public void setAllowOmitNumbersInQuantifiers(boolean allowOmitNumbersInQuantifiers) { + myAllowOmitNumbersInQuantifiers = allowOmitNumbersInQuantifiers; + } + + @NotNull + public ASTNode parse(IElementType root, PsiBuilder builder) { // builder.setDebugMode(true); - final PsiBuilder.Marker rootMarker = builder.mark(); + final PsiBuilder.Marker rootMarker = builder.mark(); - parsePattern(builder); + parsePattern(builder); - while (!builder.eof()) { - patternExpected(builder); - builder.advanceLexer(); - } - - rootMarker.done(root); - return builder.getTreeBuilt(); + while (!builder.eof()) { + patternExpected(builder); + builder.advanceLexer(); } + rootMarker.done(root); + return builder.getTreeBuilt(); + } - /** - * PATTERN ::= BRANCH "|" PATTERN | BRANCH - */ - private boolean parsePattern(PsiBuilder builder) { - final PsiBuilder.Marker marker = builder.mark(); - if (!parseBranch(builder)) { - marker.drop(); - return false; - } + /** + * PATTERN ::= BRANCH "|" PATTERN | BRANCH + */ + private boolean parsePattern(PsiBuilder builder) { + final PsiBuilder.Marker marker = builder.mark(); - while (builder.getTokenType() == RegExpTT.UNION) { - builder.advanceLexer(); - if (!parseBranch(builder)) { - // TODO: no test coverage - patternExpected(builder); - break; - } - } - - marker.done(RegExpElementTypes.PATTERN); - - return true; + if (!parseBranch(builder)) { + marker.drop(); + return false; } - /** - * BRANCH ::= ATOM BRANCH | "" - */ - @SuppressWarnings({ "StatementWithEmptyBody" }) - private boolean parseBranch(PsiBuilder builder) { - PsiBuilder.Marker marker = builder.mark(); + while (builder.getTokenType() == RegExpTT.UNION) { + builder.advanceLexer(); + if (!parseBranch(builder)) { + // TODO: no test coverage + patternExpected(builder); + break; + } + } - if (!parseAtom(builder)) { - final IElementType token = builder.getTokenType(); - if (token == RegExpTT.GROUP_END || token == RegExpTT.UNION || token == null) { - // empty branches are allowed - marker.done(RegExpElementTypes.BRANCH); - return true; - } - marker.drop(); - return false; - } + marker.done(RegExpElementTypes.PATTERN); - for (;parseAtom(builder);) ; + return true; + } + /** + * BRANCH ::= ATOM BRANCH | "" + */ + @SuppressWarnings({"StatementWithEmptyBody"}) + private boolean parseBranch(PsiBuilder builder) { + PsiBuilder.Marker marker = builder.mark(); + + if (!parseAtom(builder)) { + final IElementType token = builder.getTokenType(); + if (token == RegExpTT.GROUP_END || token == RegExpTT.UNION || token == null) { + // empty branches are allowed marker.done(RegExpElementTypes.BRANCH); return true; + } + marker.drop(); + return false; } - /** - * ATOM ::= CLOSURE | GROUP - * CLOSURE ::= GROUP QUANTIFIER - */ - private boolean parseAtom(PsiBuilder builder) { - PsiBuilder.Marker marker = parseGroup(builder); + for (; parseAtom(builder);) ; - if (marker == null) { - return false; - } - marker = marker.precede(); + marker.done(RegExpElementTypes.BRANCH); + return true; + } - if (parseQuantifier(builder)) { - marker.done(RegExpElementTypes.CLOSURE); - } else { - marker.drop(); - } + /** + * ATOM ::= CLOSURE | GROUP + * CLOSURE ::= GROUP QUANTIFIER + */ + private boolean parseAtom(PsiBuilder builder) { + PsiBuilder.Marker marker = parseGroup(builder); - return true; + if (marker == null) { + return false; + } + marker = marker.precede(); + + if (parseQuantifier(builder)) { + marker.done(RegExpElementTypes.CLOSURE); + } + else { + marker.drop(); } - /** - * QUANTIFIER ::= Q TYPE | "" - * Q ::= "{" BOUND "}" | "*" | "?" | "+" - * BOUND ::= NUM | NUM "," | NUM "," NUM - * TYPE ::= "?" | "+" | "" - */ - private boolean parseQuantifier(PsiBuilder builder) { - final PsiBuilder.Marker marker = builder.mark(); + return true; + } - if (builder.getTokenType() == RegExpTT.LBRACE) { - builder.advanceLexer(); - if (builder.getTokenType() != RegExpTT.NUMBER && myAllowDanglingMetacharacters) { - marker.done(RegExpTT.CHARACTER); - return true; - } - checkMatches(builder, RegExpTT.NUMBER, "Number expected"); - if (builder.getTokenType() == RegExpTT.RBRACE) { - builder.advanceLexer(); - parseQuantifierType(builder); - marker.done(RegExpElementTypes.QUANTIFIER); - } else { - checkMatches(builder, RegExpTT.COMMA, "',' expected"); - if (builder.getTokenType() == RegExpTT.RBRACE) { - builder.advanceLexer(); - parseQuantifierType(builder); - marker.done(RegExpElementTypes.QUANTIFIER); - } else if (builder.getTokenType() == RegExpTT.NUMBER) { - builder.advanceLexer(); - checkMatches(builder, RegExpTT.RBRACE, "'}' expected"); - parseQuantifierType(builder); - marker.done(RegExpElementTypes.QUANTIFIER); - } else { - builder.error("'}' or number expected"); - marker.done(RegExpElementTypes.QUANTIFIER); - return true; - } - } - } else if (RegExpTT.QUANTIFIERS.contains(builder.getTokenType())) { - builder.advanceLexer(); - parseQuantifierType(builder); - marker.done(RegExpElementTypes.QUANTIFIER); - } else { - marker.drop(); - return false; - } + /** + * QUANTIFIER ::= Q TYPE | "" + * Q ::= "{" BOUND "}" | "*" | "?" | "+" + * BOUND ::= NUM | NUM "," | NUM "," NUM + * TYPE ::= "?" | "+" | "" + */ + private boolean parseQuantifier(PsiBuilder builder) { + final PsiBuilder.Marker marker = builder.mark(); - return true; - } - - private static void parseQuantifierType(PsiBuilder builder) { - if (builder.getTokenType() == RegExpTT.PLUS) { - builder.advanceLexer(); - } else if (builder.getTokenType() == RegExpTT.QUEST) { - builder.advanceLexer(); - } else { - if (RegExpTT.QUANTIFIERS.contains(builder.getTokenType())) { - builder.error("Dangling metacharacter"); - } - } - } - - /** - * CLASS ::= "[" NEGATION DEFLIST "]" - * NEGATION ::= "^" | "" - * DEFLIST ::= INTERSECTION DEFLIST - * INTERSECTION ::= INTERSECTION "&&" CLASSDEF | CLASSDEF - * CLASSDEF ::= CLASS | SIMPLE_CLASSDEF | "" - * SIMPLE_CLASSDEF ::= CHARACTER | CHARACTER "-" CLASSDEF - */ - private PsiBuilder.Marker parseClass(PsiBuilder builder) { - final PsiBuilder.Marker marker = builder.mark(); + if (builder.getTokenType() == RegExpTT.LBRACE) { + builder.advanceLexer(); + boolean minOmitted = false; + if (builder.getTokenType() == RegExpTT.COMMA && myAllowOmitNumbersInQuantifiers) { + minOmitted = true; builder.advanceLexer(); - - if (builder.getTokenType() == RegExpTT.CARET) { - builder.advanceLexer(); - } - - // DEFLIST - if (parseClassIntersection(builder)) { - while (RegExpTT.CHARACTERS2.contains(builder.getTokenType()) - || builder.getTokenType() == RegExpTT.CLASS_BEGIN - || builder.getTokenType() == RegExpTT.PROPERTY) - { - parseClassIntersection(builder); - } - } - - checkMatches(builder, RegExpTT.CLASS_END, "Unclosed character class"); - marker.done(RegExpElementTypes.CLASS); - return marker; - } - - private boolean parseClassIntersection(PsiBuilder builder) { - PsiBuilder.Marker marker = builder.mark(); - - if (!parseClassdef(builder, false)) { - marker.drop(); - return false; - } - while (RegExpTT.ANDAND == builder.getTokenType()) { - builder.advanceLexer(); - parseClassdef(builder, true); - marker.done(RegExpElementTypes.INTERSECTION); - marker = marker.precede(); - } - - marker.drop(); + } + else if (builder.getTokenType() != RegExpTT.NUMBER && myAllowDanglingMetacharacters) { + marker.done(RegExpTT.CHARACTER); return true; - } - - private boolean parseClassdef(PsiBuilder builder, boolean mayBeEmpty) { - final IElementType token = builder.getTokenType(); - if (token == RegExpTT.CLASS_BEGIN) { - parseClass(builder); - } else if (RegExpTT.CHARACTERS2.contains(token)) { - parseSimpleClassdef(builder); - } else if (token == RegExpTT.PROPERTY) { - parseProperty(builder); - } else if (mayBeEmpty) { - // TODO: no test coverage - return true; - } else { - return false; - } - return true; - } - - private void parseSimpleClassdef(PsiBuilder builder) { - assert RegExpTT.CHARACTERS2.contains(builder.getTokenType()); - - final PsiBuilder.Marker marker = builder.mark(); - makeChar(builder); - - IElementType t = builder.getTokenType(); - if (t == RegExpTT.MINUS) { - final PsiBuilder.Marker m = builder.mark(); - builder.advanceLexer(); - - t = builder.getTokenType(); - if (RegExpTT.CHARACTERS2.contains(t)) { - m.drop(); - makeChar(builder); - marker.done(RegExpElementTypes.CHAR_RANGE); - } else { - marker.drop(); - m.done(t == RegExpTT.CHAR_CLASS ? - RegExpElementTypes.SIMPLE_CLASS : - RegExpElementTypes.CHAR); - - if (t == RegExpTT.CLASS_END) { // [a-] - return; - } else if (t == RegExpTT.CLASS_BEGIN) { // [a-[b]] - if (parseClassdef(builder, false)) { - return; - } - } - builder.error("Illegal character range"); - } - } else { - marker.drop(); - } - } - - private static void makeChar(PsiBuilder builder) { - final IElementType t = builder.getTokenType(); - PsiBuilder.Marker m = builder.mark(); + } + else { + checkMatches(builder, RegExpTT.NUMBER, "Number expected"); + } + if (builder.getTokenType() == RegExpTT.RBRACE) { builder.advanceLexer(); - m.done(t == RegExpTT.CHAR_CLASS ? - RegExpElementTypes.SIMPLE_CLASS : - RegExpElementTypes.CHAR); - } - - /** - * GROUP ::= "(" PATTERN ")" | TERM - * TERM ::= "." | "$" | "^" | CHAR | CLASS | BACKREF - */ - @Nullable - private PsiBuilder.Marker parseGroup(PsiBuilder builder) { - final IElementType type = builder.getTokenType(); - - final PsiBuilder.Marker marker = builder.mark(); - - if (RegExpTT.GROUPS.contains(type)) { - builder.advanceLexer(); - if (!parsePattern(builder)) { - patternExpected(builder); - } else { - checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group"); - } - marker.done(RegExpElementTypes.GROUP); - } else if (type == RegExpTT.SET_OPTIONS) { - builder.advanceLexer(); - - final PsiBuilder.Marker o = builder.mark(); - if (builder.getTokenType() == RegExpTT.OPTIONS_ON) { - builder.advanceLexer(); - } - if (builder.getTokenType() == RegExpTT.OPTIONS_OFF) { - builder.advanceLexer(); - } - o.done(RegExpElementTypes.OPTIONS); - - if (builder.getTokenType() == RegExpTT.COLON) { - builder.advanceLexer(); - if (!parsePattern(builder)) { - // TODO: no test coverage - patternExpected(builder); - } else { - checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group"); - } - marker.done(RegExpElementTypes.GROUP); - } else { - checkMatches(builder, RegExpTT.GROUP_END, "Unclosed options group"); - marker.done(RegExpElementTypes.SET_OPTIONS); - } - } else if (type == StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN) { - builder.error("Illegal/unsupported escape sequence"); - builder.advanceLexer(); - marker.done(RegExpElementTypes.CHAR); - } else if (RegExpTT.CHARACTERS.contains(type)) { - builder.advanceLexer(); - marker.done(RegExpElementTypes.CHAR); - } else if (RegExpTT.BOUNDARIES.contains(type)) { - builder.advanceLexer(); - marker.done(RegExpElementTypes.BOUNDARY); - } else if (type == RegExpTT.BACKREF) { - builder.advanceLexer(); - marker.done(RegExpElementTypes.BACKREF); - } else if (type == RegExpTT.PYTHON_NAMED_GROUP || type == RegExpTT.RUBY_NAMED_GROUP || type == RegExpTT.RUBY_QUOTED_NAMED_GROUP) { - builder.advanceLexer(); - checkMatches(builder, RegExpTT.NAME, "Group name expected"); - checkMatches(builder, type == RegExpTT.RUBY_QUOTED_NAMED_GROUP ? RegExpTT.QUOTE : RegExpTT.GT, "Unclosed group name"); - if (!parsePattern(builder)) { - patternExpected(builder); - } else { - checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group"); - } - marker.done(RegExpElementTypes.GROUP); - } else if (type == RegExpTT.PYTHON_NAMED_GROUP_REF) { - builder.advanceLexer(); - checkMatches(builder, RegExpTT.NAME, "Group name expected"); - checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group reference"); - marker.done(RegExpElementTypes.PY_NAMED_GROUP_REF); - } else if (type == RegExpTT.PYTHON_COND_REF) { - builder.advanceLexer(); - if (builder.getTokenType() == RegExpTT.NAME || builder.getTokenType() == RegExpTT.NUMBER) { - builder.advanceLexer(); - } - else { - builder.error("Group name or number expected"); - } - checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group reference"); - if (!parseBranch(builder)) { - patternExpected(builder); - } else { - if (builder.getTokenType() == RegExpTT.UNION) { - builder.advanceLexer(); - if (!parseBranch(builder)) { - patternExpected(builder); - } - } - checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group"); - } - marker.done(RegExpElementTypes.PY_COND_REF); - } else if (type == RegExpTT.PROPERTY) { - parseProperty(builder); - marker.done(RegExpElementTypes.PROPERTY); - } else if (RegExpTT.SIMPLE_CLASSES.contains(type)) { - builder.advanceLexer(); - marker.done(RegExpElementTypes.SIMPLE_CLASS); - } else if (type == RegExpTT.CLASS_BEGIN) { - marker.drop(); - return parseClass(builder); + parseQuantifierType(builder); + marker.done(RegExpElementTypes.QUANTIFIER); + } + else { + if (!minOmitted) { + checkMatches(builder, RegExpTT.COMMA, "',' expected"); } - else if (type == RegExpTT.LBRACE && myAllowDanglingMetacharacters) { - builder.advanceLexer(); - marker.done(RegExpElementTypes.CHAR); + if (builder.getTokenType() == RegExpTT.RBRACE) { + builder.advanceLexer(); + parseQuantifierType(builder); + marker.done(RegExpElementTypes.QUANTIFIER); + } + else if (builder.getTokenType() == RegExpTT.NUMBER) { + builder.advanceLexer(); + checkMatches(builder, RegExpTT.RBRACE, "'}' expected"); + parseQuantifierType(builder); + marker.done(RegExpElementTypes.QUANTIFIER); } else { - marker.drop(); - return null; + builder.error("'}' or number expected"); + marker.done(RegExpElementTypes.QUANTIFIER); + return true; } - return marker; + } + } + else if (RegExpTT.QUANTIFIERS.contains(builder.getTokenType())) { + builder.advanceLexer(); + parseQuantifierType(builder); + marker.done(RegExpElementTypes.QUANTIFIER); + } + else { + marker.drop(); + return false; } - private static void parseProperty(PsiBuilder builder) { - checkMatches(builder, RegExpTT.PROPERTY, "'\\p' expected"); + return true; + } - checkMatches(builder, RegExpTT.LBRACE, "Character category expected"); - if (builder.getTokenType() == RegExpTT.NAME) { - builder.advanceLexer(); - } else if (builder.getTokenType() == RegExpTT.RBRACE) { - builder.error("Empty character family"); - } else { - builder.error("Character family name expected"); - builder.advanceLexer(); - } - checkMatches(builder, RegExpTT.RBRACE, "Unclosed character family"); + private static void parseQuantifierType(PsiBuilder builder) { + if (builder.getTokenType() == RegExpTT.PLUS) { + builder.advanceLexer(); + } + else if (builder.getTokenType() == RegExpTT.QUEST) { + builder.advanceLexer(); + } + else { + if (RegExpTT.QUANTIFIERS.contains(builder.getTokenType())) { + builder.error("Dangling metacharacter"); + } + } + } + + /** + * CLASS ::= "[" NEGATION DEFLIST "]" + * NEGATION ::= "^" | "" + * DEFLIST ::= INTERSECTION DEFLIST + * INTERSECTION ::= INTERSECTION "&&" CLASSDEF | CLASSDEF + * CLASSDEF ::= CLASS | SIMPLE_CLASSDEF | "" + * SIMPLE_CLASSDEF ::= CHARACTER | CHARACTER "-" CLASSDEF + */ + private PsiBuilder.Marker parseClass(PsiBuilder builder) { + final PsiBuilder.Marker marker = builder.mark(); + builder.advanceLexer(); + + if (builder.getTokenType() == RegExpTT.CARET) { + builder.advanceLexer(); } - private static void patternExpected(PsiBuilder builder) { - final IElementType token = builder.getTokenType(); - if (token == RegExpTT.GROUP_END) { - builder.error("Unmatched closing ')'"); - } else if (RegExpTT.QUANTIFIERS.contains(token)) { - builder.error("Dangling metacharacter"); - } else { - builder.error("Pattern expected"); - } + // DEFLIST + if (parseClassIntersection(builder)) { + while (RegExpTT.CHARACTERS2.contains(builder.getTokenType()) || + builder.getTokenType() == RegExpTT.CLASS_BEGIN || + builder.getTokenType() == RegExpTT.PROPERTY) { + parseClassIntersection(builder); + } } - protected static void checkMatches(final PsiBuilder builder, final IElementType token, final String message) { - if (builder.getTokenType() == token) { - builder.advanceLexer(); - } else { - builder.error(message); - } + checkMatches(builder, RegExpTT.CLASS_END, "Unclosed character class"); + marker.done(RegExpElementTypes.CLASS); + return marker; + } + + private boolean parseClassIntersection(PsiBuilder builder) { + PsiBuilder.Marker marker = builder.mark(); + + if (!parseClassdef(builder, false)) { + marker.drop(); + return false; } + while (RegExpTT.ANDAND == builder.getTokenType()) { + builder.advanceLexer(); + parseClassdef(builder, true); + marker.done(RegExpElementTypes.INTERSECTION); + marker = marker.precede(); + } + + marker.drop(); + return true; + } + + private boolean parseClassdef(PsiBuilder builder, boolean mayBeEmpty) { + final IElementType token = builder.getTokenType(); + if (token == RegExpTT.CLASS_BEGIN) { + parseClass(builder); + } + else if (RegExpTT.CHARACTERS2.contains(token)) { + parseSimpleClassdef(builder); + } + else if (token == RegExpTT.PROPERTY) { + parseProperty(builder); + } + else if (mayBeEmpty) { + // TODO: no test coverage + return true; + } + else { + return false; + } + return true; + } + + private void parseSimpleClassdef(PsiBuilder builder) { + assert RegExpTT.CHARACTERS2.contains(builder.getTokenType()); + + final PsiBuilder.Marker marker = builder.mark(); + makeChar(builder); + + IElementType t = builder.getTokenType(); + if (t == RegExpTT.MINUS) { + final PsiBuilder.Marker m = builder.mark(); + builder.advanceLexer(); + + t = builder.getTokenType(); + if (RegExpTT.CHARACTERS2.contains(t)) { + m.drop(); + makeChar(builder); + marker.done(RegExpElementTypes.CHAR_RANGE); + } + else { + marker.drop(); + m.done(t == RegExpTT.CHAR_CLASS ? RegExpElementTypes.SIMPLE_CLASS : RegExpElementTypes.CHAR); + + if (t == RegExpTT.CLASS_END) { // [a-] + return; + } + else if (t == RegExpTT.CLASS_BEGIN) { // [a-[b]] + if (parseClassdef(builder, false)) { + return; + } + } + builder.error("Illegal character range"); + } + } + else { + marker.drop(); + } + } + + private static void makeChar(PsiBuilder builder) { + final IElementType t = builder.getTokenType(); + PsiBuilder.Marker m = builder.mark(); + builder.advanceLexer(); + m.done(t == RegExpTT.CHAR_CLASS ? RegExpElementTypes.SIMPLE_CLASS : RegExpElementTypes.CHAR); + } + + /** + * GROUP ::= "(" PATTERN ")" | TERM + * TERM ::= "." | "$" | "^" | CHAR | CLASS | BACKREF + */ + @Nullable + private PsiBuilder.Marker parseGroup(PsiBuilder builder) { + final IElementType type = builder.getTokenType(); + + final PsiBuilder.Marker marker = builder.mark(); + + if (RegExpTT.GROUPS.contains(type)) { + builder.advanceLexer(); + if (!parsePattern(builder)) { + patternExpected(builder); + } + else { + checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group"); + } + marker.done(RegExpElementTypes.GROUP); + } + else if (type == RegExpTT.SET_OPTIONS) { + builder.advanceLexer(); + + final PsiBuilder.Marker o = builder.mark(); + if (builder.getTokenType() == RegExpTT.OPTIONS_ON) { + builder.advanceLexer(); + } + if (builder.getTokenType() == RegExpTT.OPTIONS_OFF) { + builder.advanceLexer(); + } + o.done(RegExpElementTypes.OPTIONS); + + if (builder.getTokenType() == RegExpTT.COLON) { + builder.advanceLexer(); + if (!parsePattern(builder)) { + // TODO: no test coverage + patternExpected(builder); + } + else { + checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group"); + } + marker.done(RegExpElementTypes.GROUP); + } + else { + checkMatches(builder, RegExpTT.GROUP_END, "Unclosed options group"); + marker.done(RegExpElementTypes.SET_OPTIONS); + } + } + else if (type == StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN) { + builder.error("Illegal/unsupported escape sequence"); + builder.advanceLexer(); + marker.done(RegExpElementTypes.CHAR); + } + else if (RegExpTT.CHARACTERS.contains(type)) { + builder.advanceLexer(); + marker.done(RegExpElementTypes.CHAR); + } + else if (RegExpTT.BOUNDARIES.contains(type)) { + builder.advanceLexer(); + marker.done(RegExpElementTypes.BOUNDARY); + } + else if (type == RegExpTT.BACKREF) { + builder.advanceLexer(); + marker.done(RegExpElementTypes.BACKREF); + } + else if (type == RegExpTT.PYTHON_NAMED_GROUP || type == RegExpTT.RUBY_NAMED_GROUP || type == RegExpTT.RUBY_QUOTED_NAMED_GROUP) { + builder.advanceLexer(); + checkMatches(builder, RegExpTT.NAME, "Group name expected"); + checkMatches(builder, type == RegExpTT.RUBY_QUOTED_NAMED_GROUP ? RegExpTT.QUOTE : RegExpTT.GT, "Unclosed group name"); + if (!parsePattern(builder)) { + patternExpected(builder); + } + else { + checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group"); + } + marker.done(RegExpElementTypes.GROUP); + } + else if (type == RegExpTT.PYTHON_NAMED_GROUP_REF) { + builder.advanceLexer(); + checkMatches(builder, RegExpTT.NAME, "Group name expected"); + checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group reference"); + marker.done(RegExpElementTypes.PY_NAMED_GROUP_REF); + } + else if (type == RegExpTT.PYTHON_COND_REF) { + builder.advanceLexer(); + if (builder.getTokenType() == RegExpTT.NAME || builder.getTokenType() == RegExpTT.NUMBER) { + builder.advanceLexer(); + } + else { + builder.error("Group name or number expected"); + } + checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group reference"); + if (!parseBranch(builder)) { + patternExpected(builder); + } + else { + if (builder.getTokenType() == RegExpTT.UNION) { + builder.advanceLexer(); + if (!parseBranch(builder)) { + patternExpected(builder); + } + } + checkMatches(builder, RegExpTT.GROUP_END, "Unclosed group"); + } + marker.done(RegExpElementTypes.PY_COND_REF); + } + else if (type == RegExpTT.PROPERTY) { + parseProperty(builder); + marker.done(RegExpElementTypes.PROPERTY); + } + else if (RegExpTT.SIMPLE_CLASSES.contains(type)) { + builder.advanceLexer(); + marker.done(RegExpElementTypes.SIMPLE_CLASS); + } + else if (type == RegExpTT.CLASS_BEGIN) { + marker.drop(); + return parseClass(builder); + } + else if (type == RegExpTT.LBRACE && myAllowDanglingMetacharacters) { + builder.advanceLexer(); + marker.done(RegExpElementTypes.CHAR); + } + else { + marker.drop(); + return null; + } + return marker; + } + + private static void parseProperty(PsiBuilder builder) { + checkMatches(builder, RegExpTT.PROPERTY, "'\\p' expected"); + + checkMatches(builder, RegExpTT.LBRACE, "Character category expected"); + if (builder.getTokenType() == RegExpTT.NAME) { + builder.advanceLexer(); + } + else if (builder.getTokenType() == RegExpTT.RBRACE) { + builder.error("Empty character family"); + } + else { + builder.error("Character family name expected"); + builder.advanceLexer(); + } + checkMatches(builder, RegExpTT.RBRACE, "Unclosed character family"); + } + + private static void patternExpected(PsiBuilder builder) { + final IElementType token = builder.getTokenType(); + if (token == RegExpTT.GROUP_END) { + builder.error("Unmatched closing ')'"); + } + else if (RegExpTT.QUANTIFIERS.contains(token)) { + builder.error("Dangling metacharacter"); + } + else { + builder.error("Pattern expected"); + } + } + + protected static void checkMatches(final PsiBuilder builder, final IElementType token, final String message) { + if (builder.getTokenType() == token) { + builder.advanceLexer(); + } + else { + builder.error(message); + } + } } From 09ae855a49f15ef0e82ea50c1f70f1e55f60b8c3 Mon Sep 17 00:00:00 2001 From: Roman Chernyatchik Date: Tue, 1 Jun 2010 13:33:54 +0400 Subject: [PATCH 09/36] EA-20620 fixed --- .../ide/util/gotoByName/GotoActionModel.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java index 19956ca586b5..df826b1ca476 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java @@ -131,7 +131,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel { }; } - protected String getActionId(AnAction anAction) { + protected String getActionId(final @NotNull AnAction anAction) { return myActionManager.getId(anAction); } @@ -219,13 +219,15 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel { private void collectActions(String id, Map result, ActionGroup group, final String containingGroupName){ final AnAction[] actions = group.getChildren(null); for (AnAction action : actions) { - if (action instanceof ActionGroup) { - final ActionGroup actionGroup = (ActionGroup)action; - final String groupName = actionGroup.getTemplatePresentation().getText(); - collectActions(id, result, actionGroup, groupName != null ? groupName : containingGroupName); - } else if (getActionId(action) == id) { - final String groupName = group.getTemplatePresentation().getText(); - result.put(action, groupName != null && groupName.length() > 0 ? groupName : containingGroupName); + if (action != null) { + if (action instanceof ActionGroup) { + final ActionGroup actionGroup = (ActionGroup)action; + final String groupName = actionGroup.getTemplatePresentation().getText(); + collectActions(id, result, actionGroup, groupName != null ? groupName : containingGroupName); + } else if (getActionId(action) == id) { + final String groupName = group.getTemplatePresentation().getText(); + result.put(action, groupName != null && groupName.length() > 0 ? groupName : containingGroupName); + } } } } From 72e9c70c7c5d6ebf282de17959e2ed17dc7e8b45 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Sat, 5 Jun 2010 22:19:09 +0400 Subject: [PATCH 10/36] Formatter fix. Do not break modifier statements according to spacing around methods --- .../intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java index 8349d2e3792d..46906487120e 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java @@ -120,7 +120,7 @@ public class CodeFormatterFacade { PsiDocumentManager.getInstance(project).getDocument(file), project, mySettings, fileType, file); - //printToConsole(rootBlock, model); + printToConsole(rootBlock, model); FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(fileType), ranges); } From abe169eb27c59792f433b5355fbab40b23de52b7 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Sat, 5 Jun 2010 22:30:36 +0400 Subject: [PATCH 11/36] Revert "Formatter fix. Do not break modifier statements according to spacing around methods" This reverts commit 6e81663261eabfe6922a3518d0e6bef878857712. Turn off block model debug printing --- .../intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java index 46906487120e..8349d2e3792d 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeFormatterFacade.java @@ -120,7 +120,7 @@ public class CodeFormatterFacade { PsiDocumentManager.getInstance(project).getDocument(file), project, mySettings, fileType, file); - printToConsole(rootBlock, model); + //printToConsole(rootBlock, model); FormatterEx.getInstanceEx().format(model, mySettings, mySettings.getIndentOptions(fileType), ranges); } From a3d62623aa0540d5891516ef4cebd0511ff8049c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Sun, 6 Jun 2010 15:45:49 +0400 Subject: [PATCH 12/36] preselect initial text in "Run Rails generator" action --- .../ide/util/gotoByName/ChooseByNameBase.java | 12 ++++++++++++ .../ide/util/gotoByName/ChooseByNamePopup.java | 3 +++ 2 files changed, 15 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index c1b9c98767c1..c88deb758f6e 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -78,6 +78,7 @@ public abstract class ChooseByNameBase{ protected final Project myProject; protected final ChooseByNameModel myModel; protected final String myInitialText; + private boolean myPreselectInitialText; private final Reference myContext; protected Component myPreviouslyFocusedComponent; @@ -147,6 +148,14 @@ public abstract class ChooseByNameBase{ myContext = new WeakReference(context); } + public boolean isPreselectInitialText() { + return myPreselectInitialText; + } + + public void setPreselectInitialText(boolean preselectInitialText) { + myPreselectInitialText = preselectInitialText; + } + /** * Set tool area. The method may be called only before invoke. * @param toolArea a tool area component @@ -321,6 +330,9 @@ public abstract class ChooseByNameBase{ myFuture = new ArrayList>(); myTextField = new MyTextField(); myTextField.setText(myInitialText); + if (myPreselectInitialText) { + myTextField.select(0, myInitialText.length()); + } final ActionMap actionMap = new ActionMap(); actionMap.setParent(myTextField.getActionMap()); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java index 7549872216e8..7058a7aae294 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java @@ -40,6 +40,9 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP private ChooseByNamePopup(final Project project, final ChooseByNameModel model, final ChooseByNamePopup oldPopup, final PsiElement context, @Nullable final String predefinedText) { super(project, model, oldPopup != null ? oldPopup.getEnteredText() : predefinedText, context); + if (oldPopup == null && predefinedText != null) { + setPreselectInitialText(true); + } if (oldPopup != null) { //inherit old focus owner myOldFocusOwner = oldPopup.myPreviouslyFocusedComponent; } From c75151683bcb15e204f62dea90c4803b0016ef5b Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 7 Jun 2010 01:30:33 +0400 Subject: [PATCH 13/36] initial implementation of autotest for Ruby --- .../com/intellij/execution/ui/RunContentDescriptor.java | 9 +++++++++ .../com/intellij/execution/runners/RestartAction.java | 9 +++++++++ .../intellij/execution/runners/RunContentBuilder.java | 5 +++++ .../com/intellij/execution/ui/RunContentManagerImpl.java | 2 +- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java b/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java index 1ae6900a9356..645f35a26f69 100644 --- a/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java +++ b/platform/lang-api/src/com/intellij/execution/ui/RunContentDescriptor.java @@ -40,6 +40,7 @@ public class RunContentDescriptor { * Used to hack {@link com.intellij.execution.runners.RestartAction} */ private Content myContent; + private Runnable myRestarter; public RunContentDescriptor(final ExecutionConsole executionConsole, final ProcessHandler processHandler, final JComponent component, final String displayName, final Icon icon) { @@ -108,4 +109,12 @@ public class RunContentDescriptor { public Content getAttachedContent() { return myContent; } + + public void setRestarter(Runnable runnable) { + myRestarter = runnable; + } + + public Runnable getRestarter() { + return myRestarter; + } } diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java index 95d58bbed939..6dae50b9f732 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/RestartAction.java @@ -21,6 +21,7 @@ import com.intellij.execution.Executor; import com.intellij.execution.RunCanceledByUserException; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.project.DumbAware; @@ -57,6 +58,14 @@ public class RestartAction extends AnAction implements DumbAware { public void actionPerformed(final AnActionEvent e) { final DataContext dataContext = e.getDataContext(); + doRestart(dataContext); + } + + public void restart() { + doRestart(DataManager.getInstance().getDataContext(myDescriptor.getComponent())); + } + + private void doRestart(final DataContext dataContext) { final Project project = PlatformDataKeys.PROJECT.getData(dataContext); try { final ExecutionEnvironment old = myEnvironment; diff --git a/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java b/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java index d6f01d823201..2e90764ca8aa 100644 --- a/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java +++ b/platform/lang-impl/src/com/intellij/execution/runners/RunContentBuilder.java @@ -199,6 +199,11 @@ public class RunContentBuilder implements LogConsoleManager, Disposable { final RestartAction restartAction = new RestartAction(myExecutor, myRunner, getProcessHandler(), myRerunIcon, contentDescriptor, myEnvironment); restartAction.registerShortcut(component); actionGroup.add(restartAction); + contentDescriptor.setRestarter(new Runnable() { + public void run() { + restartAction.restart(); + } + }); if (myExecutionResult instanceof DefaultExecutionResult) { final AnAction[] actions = ((DefaultExecutionResult)myExecutionResult).getRestartActions(); diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index 90b65bfd1e26..9b3c4fa34f37 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -392,7 +392,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { } } - private static RunContentDescriptor getRunContentDescriptorByContent(final Content content) { + public static RunContentDescriptor getRunContentDescriptorByContent(final Content content) { return content.getUserData(DESCRIPTOR_KEY); } From 942d4ddca9f30597f5daa8126873387cb6064be4 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 18 Jun 2010 19:45:45 +0400 Subject: [PATCH 14/36] move 'Move Module To Group' from lang to idea --- platform/platform-resources/src/idea/LangActions.xml | 4 +--- resources/src/idea/IdeaActions.xml | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 558ffac8dea7..31398574a513 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -6,8 +6,7 @@ - - + @@ -392,7 +391,6 @@ - diff --git a/resources/src/idea/IdeaActions.xml b/resources/src/idea/IdeaActions.xml index 67df97c82378..3afaf6fb2804 100644 --- a/resources/src/idea/IdeaActions.xml +++ b/resources/src/idea/IdeaActions.xml @@ -345,6 +345,7 @@ + @@ -381,6 +382,10 @@ + + + + From 32daaf7eb0b31158f6de5fe18ed5de2095bfc4cf Mon Sep 17 00:00:00 2001 From: Constantine Plotnikov Date: Thu, 24 Jun 2010 17:15:23 +0400 Subject: [PATCH 15/36] git4idea: Renamed application settings service in XML files --- .../src/git4idea/config/GitVcsApplicationSettings.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/git4idea/src/git4idea/config/GitVcsApplicationSettings.java b/plugins/git4idea/src/git4idea/config/GitVcsApplicationSettings.java index b360b3050052..6935852252b9 100644 --- a/plugins/git4idea/src/git4idea/config/GitVcsApplicationSettings.java +++ b/plugins/git4idea/src/git4idea/config/GitVcsApplicationSettings.java @@ -27,9 +27,9 @@ import java.io.File; * The application wide settings for the git */ @State( - name = "PasswordSafe", + name = "Git.Application.Settings", storages = {@Storage( - id = "PasswordSafe", + id = "Git.Application.Settings", file = "$APP_CONFIG$/vcs.xml")}) public class GitVcsApplicationSettings implements PersistentStateComponent { /** From f178c4ddeea35c37bca8c030faa7d88cb4624fec Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 16:40:47 +0400 Subject: [PATCH 16/36] ClsMethod.getNavigationElement() may be not a method anymore --- .../intellij/psi/impl/compiled/ClsMethodImpl.java | 15 ++++++++++----- .../psi/impl/compiled/ClsParameterImpl.java | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java index 81b7dc25baf5..4dd8694e3f57 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java @@ -336,18 +336,23 @@ public class ClsMethodImpl extends ClsRepositoryPsiElement implem } @NotNull - public PsiElement getNavigationElement() { + public PsiMethod getSourceMirrorMethod() { PsiClass sourceClassMirror = ((ClsClassImpl)getParent()).getSourceMirrorClass(); if (sourceClassMirror == null) return this; - final PsiMethod[] methodsByName = sourceClassMirror.findMethodsByName(getName(), false); - for (PsiMethod sourceMethod : methodsByName) { - if (MethodSignatureUtil.areParametersErasureEqual(this, sourceMethod) && sourceMethod != this) { - return sourceMethod.getNavigationElement(); + for (PsiMethod sourceMethod : sourceClassMirror.findMethodsByName(getName(), false)) { + if (MethodSignatureUtil.areParametersErasureEqual(this, sourceMethod)) { + return sourceMethod; } } return this; } + @NotNull + public PsiElement getNavigationElement() { + final PsiMethod method = getSourceMirrorMethod(); + return method != this ? method.getNavigationElement() : this; + } + public PsiTypeParameterList getTypeParameterList() { return getStub().findChildStubByType(JavaStubElementTypes.TYPE_PARAMETER_LIST).getPsi(); } diff --git a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java index da8235e5e427..63dbd4fbd8f3 100644 --- a/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java @@ -63,7 +63,7 @@ public class ClsParameterImpl extends ClsRepositoryPsiElement } ClsMethodImpl method = (ClsMethodImpl)getDeclarationScope(); - PsiMethod sourceMethod = (PsiMethod)method.getNavigationElement(); + PsiMethod sourceMethod = method.getSourceMirrorMethod(); if (sourceMethod == method) { final PsiParameterStubImpl parameterStub = (PsiParameterStubImpl) getStub(); if (!parameterStub.isAutoGeneratedName()) { From 1c66c2d26df3dc4a2f9a7874262346bc56c3a5ba Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 17:39:24 +0400 Subject: [PATCH 17/36] yet another attempt to handle spaces in URLs --- .../groovy/compiler/rt/GroovycRunner.java | 17 +++++++++++++---- .../groovy/compiler/GroovyCompilerBase.java | 5 +---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java index 57865443cb40..d7635078decd 100644 --- a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java +++ b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java @@ -24,6 +24,8 @@ import org.codehaus.groovy.tools.javac.JavaAwareResolveVisitor; import org.codehaus.groovy.tools.javac.JavaStubGenerator; import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; @@ -341,10 +343,17 @@ public class GroovycRunner { final Enumeration resources = super.getResources(name); final ArrayList list = Collections.list(resources); for (Iterator iterator = list.iterator(); iterator.hasNext();) { - String file = ((URL)iterator.next()).getFile(); - System.out.println("Enumerated:" + file); - if (file.startsWith(finalOutput) || file.startsWith("/" + finalOutput)) { - iterator.remove(); + final URL url = (URL)iterator.next(); + if ("file".equals(url.getProtocol())) { + try { + final String file = new File(new URI(url.toString())).getCanonicalPath(); + System.out.println("Enumerated:" + file); + if (file.startsWith(finalOutput) || file.startsWith("/" + finalOutput)) { + iterator.remove(); + } + } + catch (URISyntaxException ignored) { + } } } return Collections.enumeration(list); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java index 8e74963b88ee..50a5991ce0bc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/compiler/GroovyCompilerBase.java @@ -71,7 +71,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.util.GroovyUtils; import java.io.*; -import java.net.URL; import java.nio.charset.Charset; import java.util.*; @@ -304,9 +303,7 @@ public abstract class GroovyCompilerBase implements TranslatingCompiler { printer.println(PathUtil.getLocalPath(outputDir)); printer.println(GroovycRunner.FINAL_OUTPUTPATH); - final URL finalUrl = VfsUtil.convertToURL(finalOutputDir.getUrl()); - LOG.assertTrue(finalUrl != null, finalOutputDir.getPath()); - printer.println(finalUrl.getFile()); + printer.println(FileUtil.toSystemDependentName(finalOutputDir.getPath())); printer.close(); From 77cb56f5916b0289e071d4cdc962acc93dd53ca5 Mon Sep 17 00:00:00 2001 From: Alexey Pegov Date: Thu, 24 Jun 2010 18:02:53 +0400 Subject: [PATCH 18/36] statusbar progress text slipping --- .../impl/status/InlineProgressIndicator.java | 1 + .../openapi/wm/impl/status/TextPanel.java | 20 +++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java index adf3812b3191..fd8a68555de8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java @@ -86,6 +86,7 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di textAndProgress.add(myText, BorderLayout.CENTER); final NonOpaquePanel progressWrapper = new NonOpaquePanel(new GridBagLayout()); + progressWrapper.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 0)); final GridBagConstraints c = new GridBagConstraints(); c.weightx = 1; c.weighty = 1; diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java index f70ddb2ba90f..83a400d1f9dd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/TextPanel.java @@ -58,7 +58,7 @@ public class TextPanel extends JComponent { @Override protected void paintComponent(final Graphics g) { - final String s = getText(); + String s = getText(); if (s != null) { final Rectangle bounds = getBounds(); final Insets insets = getInsets(); @@ -68,12 +68,28 @@ public class TextPanel extends JComponent { UIUtil.applyRenderingHints(g2); + final FontMetrics fm = g2.getFontMetrics(); + final int sWidth = fm.stringWidth(s); + int x = insets.left; if (myAlignment == JComponent.CENTER_ALIGNMENT || myAlignment == JComponent.RIGHT_ALIGNMENT) { - final int sWidth = g2.getFontMetrics().stringWidth(s); x = myAlignment == JComponent.CENTER_ALIGNMENT ? (bounds.width - sWidth) / 2 : bounds.width - insets.right - sWidth; } + final Rectangle textR = new Rectangle(); + final Rectangle iconR = new Rectangle(); + final Rectangle viewR = new Rectangle(bounds); + textR.x = textR.y = textR.width = textR.height = 0; + + viewR.width -= insets.left; + viewR.width -= insets.right; + + if (sWidth > (bounds.width - insets.left - insets.right)) { + s = SwingUtilities + .layoutCompoundLabel(fm, s, null, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.TRAILING, + bounds, iconR, textR, 0); + } + final int y = UIUtil.getStringY(s, bounds, g2); if (SystemInfo.isMac && myDecorate) { g2.setColor(new Color(215, 215, 215)); From ddd61fab040262e3fd9ae98e2d4bdbeff9d16744 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 24 Jun 2010 16:01:16 +0400 Subject: [PATCH 19/36] narrow down throws clause --- .../intellij/testFramework/ParsingTestCase.java | 14 +++++++------- .../src/com/intellij/lang/ant/CustomTypesTest.java | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java b/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java index a6393382fb7f..cea036ac61e4 100644 --- a/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/ParsingTestCase.java @@ -53,7 +53,7 @@ public abstract class ParsingTestCase extends LightPlatformTestCase { return false; } - protected void doTest(boolean checkResult) throws Exception{ + protected void doTest(boolean checkResult) throws Exception { String name = getTestName(false); String text = loadFile(name + "." + myFileExt); myFile = createPsiFile(name, text); @@ -67,7 +67,7 @@ public abstract class ParsingTestCase extends LightPlatformTestCase { } } - protected void doTest(String suffix) throws Exception{ + protected void doTest(String suffix) throws IOException { String name = getTestName(false); String text = loadFile(name + "." + myFileExt); myFile = createPsiFile(name, text); @@ -80,11 +80,11 @@ public abstract class ParsingTestCase extends LightPlatformTestCase { return createFile(name + "." + myFileExt, text); } - protected void checkResult(@NonNls @TestDataFile String targetDataName, final PsiFile file) throws Exception { + protected void checkResult(@NonNls @TestDataFile String targetDataName, final PsiFile file) throws IOException { doCheckResult(myFullDataPath, file, targetDataName, includeRanges()); } - public static void doCheckResult(String myFullDataPath, PsiFile file, String targetDataName, boolean printRanges) throws Exception { + public static void doCheckResult(String myFullDataPath, PsiFile file, String targetDataName, boolean printRanges) throws IOException { final PsiElement[] psiRoots = file.getPsiRoots(); if(psiRoots.length > 1){ for (int i = 0; i < psiRoots.length; i++) { @@ -97,11 +97,11 @@ public abstract class ParsingTestCase extends LightPlatformTestCase { } } - protected void checkResult(@TestDataFile @NonNls String targetDataName, final String text) throws Exception { + protected void checkResult(@TestDataFile @NonNls String targetDataName, final String text) throws IOException { doCheckResult(myFullDataPath, targetDataName, text); } - private static void doCheckResult(String myFullDataPath, String targetDataName, String text) throws Exception { + private static void doCheckResult(String myFullDataPath, String targetDataName, String text) throws IOException { try { text = text.trim(); String expectedText = doLoadFile(myFullDataPath, targetDataName); @@ -124,7 +124,7 @@ public abstract class ParsingTestCase extends LightPlatformTestCase { return DebugUtil.psiToString(file, false, printRanges); } - protected String loadFile(@NonNls @TestDataFile String name) throws Exception { + protected String loadFile(@NonNls @TestDataFile String name) throws IOException { return doLoadFile(myFullDataPath, name); } diff --git a/plugins/ant/tests/src/com/intellij/lang/ant/CustomTypesTest.java b/plugins/ant/tests/src/com/intellij/lang/ant/CustomTypesTest.java index e164c87b1fd0..f26f08fcc99f 100644 --- a/plugins/ant/tests/src/com/intellij/lang/ant/CustomTypesTest.java +++ b/plugins/ant/tests/src/com/intellij/lang/ant/CustomTypesTest.java @@ -26,6 +26,7 @@ import com.intellij.testFramework.ParsingTestCase; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.io.IOException; public class CustomTypesTest extends ParsingTestCase { @@ -63,7 +64,7 @@ public class CustomTypesTest extends ParsingTestCase { return result; } - protected String loadFile(String name) throws Exception { + protected String loadFile(String name) throws IOException { String fullName = getTestDataPath() + File.separatorChar + name; String text = new String(FileUtil.loadFileText(new File(fullName))).trim(); text = StringUtil.convertLineSeparators(text); From 05c5a8d72f8cca2c81afebb7c9813e10f04982c8 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Thu, 24 Jun 2010 19:46:36 +0400 Subject: [PATCH 20/36] IDEA-55965 AIOOBE in CompletionLookupArranger --- .../codeInsight/completion/CompletionLookupArranger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index 9c9068afcb66..2f5d41ff77db 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -126,7 +126,7 @@ public class CompletionLookupArranger extends LookupArranger { for (int i = 0; i < weight1.length; i++) { final Comparable w1 = weight1[i]; - final Comparable w2 = weight2[i]; + final Comparable w2 = i < weight2.length ? weight2[i]:null; if (w1 != null || w2 != null) { if (w1 == null) return 1; if (w2 == null) return -1; From 99719e1d4280ef5573affcaa431d74c9679a3dfc Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 24 Jun 2010 19:50:00 +0400 Subject: [PATCH 21/36] "Analyze stacktrace" does something useful in PyCharm (PY-1128) --- .../intellij/unscramble/AnalyzeStacktraceUtil.java | 13 ++++++++++++- .../src/META-INF/LangExtensionPoints.xml | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java b/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java index 8c66960581f3..5a62e1b22d77 100644 --- a/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java +++ b/platform/lang-impl/src/com/intellij/unscramble/AnalyzeStacktraceUtil.java @@ -19,6 +19,8 @@ package com.intellij.unscramble; import com.intellij.execution.ExecutionManager; import com.intellij.execution.Executor; import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.filters.Filter; +import com.intellij.execution.filters.TextConsoleBuilder; import com.intellij.execution.filters.TextConsoleBuilderFactory; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; @@ -33,6 +35,8 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.EditorSettings; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; @@ -48,6 +52,8 @@ import java.awt.datatransfer.Transferable; * @author yole */ public class AnalyzeStacktraceUtil { + public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.analyzeStacktraceFilter"); + private AnalyzeStacktraceUtil() { } @@ -82,7 +88,12 @@ public class AnalyzeStacktraceUtil { } public static ConsoleView addConsole(Project project, @Nullable ConsoleFactory consoleFactory, final String tabTitle) { - final ConsoleView consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole(); + final TextConsoleBuilder builder = TextConsoleBuilderFactory.getInstance().createBuilder(project); + for(Filter filter: Extensions.getExtensions(EP_NAME, project)) { + builder.addFilter(filter); + } + + final ConsoleView consoleView = builder.getConsole(); final DefaultActionGroup toolbarActions = new DefaultActionGroup(); JComponent consoleComponent = consoleFactory != null ? consoleFactory.createConsoleComponent(consoleView, toolbarActions) diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 90f4aceaf5ed..f970c2265fe9 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -436,4 +436,6 @@ + + From 1823c65603053d7fb5b5431caa02e474d6623a11 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 24 Jun 2010 20:04:47 +0400 Subject: [PATCH 22/36] EA-20891 - CCE: FileTextFieldImpl. --- .../com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java index a95469888f25..b87190034ab5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileTextFieldImpl.java @@ -99,7 +99,7 @@ public abstract class FileTextFieldImpl implements FileLookup, Disposable, FileT for (KeyStroke eachListStroke : listKeys) { final String listActionID = (String)listMap.get(eachListStroke); if ("selectNextRow".equals(listActionID) || "selectPreviousRow".equals(listActionID)) { - final String textActionID = (String)field.getInputMap().get(eachListStroke); + final Object textActionID = field.getInputMap().get(eachListStroke); if (textActionID != null) { final Action textAction = field.getActionMap().get(textActionID); if (textAction != null) { From ec294544ba3ad45719bf37b78170de799f909107 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Thu, 24 Jun 2010 20:21:11 +0400 Subject: [PATCH 23/36] correct zen-coding behavior inside injected fragment (fix EA-20896), clean up --- .../template/CustomTemplateCallback.java | 14 ++++++++++++-- .../template/zencoding/XmlZenCodingTemplate.java | 6 ++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java b/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java index 3d96a531ea0f..d3879d626ec3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java @@ -22,6 +22,7 @@ import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileFactory; @@ -54,10 +55,19 @@ public class CustomTemplateCallback { private int myOffset = 0; public CustomTemplateCallback(Editor editor, PsiFile file) { - myEditor = editor; - myFile = file; myProject = file.getProject(); myTemplateManager = TemplateManagerImpl.getInstance(myProject); + + int caretOffset = editor.getCaretModel().getOffset(); + + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + PsiElement element = InjectedLanguageUtil.findElementAtNoCommit(file, caretOffset); + + myFile = element != null ? element.getContainingFile() : file; + + myEditor = InjectedLanguageManager.getInstance(myProject).isInjectedFragment(myFile) ? InjectedLanguageUtil + .getEditorForInjectedLanguageNoCommit(editor, file) : editor; + fixInitialState(); } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java index d1a9ecb9a32e..af36da5fb8a8 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java @@ -336,15 +336,13 @@ public class XmlZenCodingTemplate extends ZenCodingTemplate { int lineStart = editor.getDocument().getLineStartOffset(line); int elementStart; do { - elementStart = element != null ? element.getTextRange().getStartOffset() : 0; + elementStart = element.getTextRange().getStartOffset(); int startOffset = elementStart > lineStart ? elementStart : lineStart; String key = computeKey(editor, startOffset); if (checkTemplateKey(key, callback)) { return key; } - if (element != null) { - element = element.getParent(); - } + element = element.getParent(); } while (element != null && elementStart > lineStart); return null; From dae3f5ccf0bdabd5fc8563ee4c38926e9f075966 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Thu, 24 Jun 2010 20:39:23 +0400 Subject: [PATCH 24/36] toString methods for tokens; log E-20609 --- .../intellij/codeInsight/template/zencoding/FilterToken.java | 5 +++++ .../intellij/codeInsight/template/zencoding/MarkerToken.java | 4 ++++ .../intellij/codeInsight/template/zencoding/NumberToken.java | 5 +++++ .../codeInsight/template/zencoding/OperationToken.java | 5 +++++ .../codeInsight/template/zencoding/TemplateToken.java | 5 +++++ .../template/zencoding/XmlZenCodingInterpreter.java | 4 ++-- 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/FilterToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/FilterToken.java index 4a79f392a302..82c3f8f24e21 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/FilterToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/FilterToken.java @@ -28,4 +28,9 @@ public class FilterToken extends Token { public String getSuffix() { return mySuffix; } + + @Override + public String toString() { + return "|" + mySuffix; + } } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/MarkerToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/MarkerToken.java index ba9c9af1b9c8..54f54f810c59 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/MarkerToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/MarkerToken.java @@ -19,4 +19,8 @@ package com.intellij.codeInsight.template.zencoding; * @author Eugene.Kudelevsky */ class MarkerToken extends Token { + @Override + public String toString() { + return "&"; + } } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/NumberToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/NumberToken.java index d101c8f4325f..ffea97d94ac6 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/NumberToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/NumberToken.java @@ -28,4 +28,9 @@ class NumberToken extends Token { public int getNumber() { return myNumber; } + + @Override + public String toString() { + return Integer.toString(myNumber); + } } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/OperationToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/OperationToken.java index b33e164eee8e..1cd3acbd566b 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/OperationToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/OperationToken.java @@ -28,4 +28,9 @@ class OperationToken extends Token { public char getSign() { return mySign; } + + @Override + public String toString() { + return Character.toString(mySign); + } } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/TemplateToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/TemplateToken.java index 1a0f490fbe64..3257ccc9d49c 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/TemplateToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/TemplateToken.java @@ -39,4 +39,9 @@ public class TemplateToken extends Token { public TemplateImpl getTemplate() { return myTemplate; } + + @Override + public String toString() { + return "TEMPLATE"; + } } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java index 5ad53eec3a94..01ffb0dda8a2 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java @@ -372,7 +372,7 @@ class XmlZenCodingInterpreter { return new XmlZenCodingFilterImpl().toString(tag, context); } - private static void fail() { - LOG.error("Input string was checked incorrectly during isApplicable() invokation"); + private void fail() { + LOG.error("Input string was checked incorrectly during isApplicable() invokation: " + myTokens.toString()); } } From 478bad3a5f66d21a8c44f6659241a76611df54ce Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Thu, 24 Jun 2010 21:39:38 +0400 Subject: [PATCH 25/36] test, do not reformat zen-coding result inside injected context --- .../codeInsight/template/CustomTemplateCallback.java | 12 +++++------- .../codeInsight/template/LiveTemplateBuilder.java | 1 - .../template/zencoding/XmlZenCodingInterpreter.java | 1 - 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java b/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java index d3879d626ec3..45c8a6f7e0b0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java @@ -49,6 +49,8 @@ public class CustomTemplateCallback { private LiveTemplateBuilder.Marker myEndOffsetMarker; private final Map myCheckpoints = new HashMap(); + private final boolean myInInjectedFragment; + private FileType myFileType; private LiveTemplateBuilder myBuilder = new LiveTemplateBuilder(); @@ -65,8 +67,8 @@ public class CustomTemplateCallback { myFile = element != null ? element.getContainingFile() : file; - myEditor = InjectedLanguageManager.getInstance(myProject).isInjectedFragment(myFile) ? InjectedLanguageUtil - .getEditorForInjectedLanguageNoCommit(editor, file) : editor; + myInInjectedFragment = InjectedLanguageManager.getInstance(myProject).isInjectedFragment(myFile); + myEditor = myInInjectedFragment ? InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(editor, file) : editor; fixInitialState(); } @@ -161,11 +163,6 @@ public class CustomTemplateCallback { } public void startAllExpandedTemplates() { - /*myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - final CodeStyleManager style = CodeStyleManager.getInstance(myProject); - if (myGlobalMarker != null) { - style.reformatText(myFile, myGlobalMarker.getStartOffset(), myGlobalMarker.getEndOffset()); - }*/ if (myBuilder.getText().length() == 0) { return; } @@ -174,6 +171,7 @@ public class CustomTemplateCallback { myBuilder.insertVariableSegment(myOffset, TemplateImpl.END); } TemplateImpl template = myBuilder.buildTemplate(); + template.setToReformat(!myInInjectedFragment); myTemplateManager.startTemplate(myEditor, template, false, myBuilder.getPredefinedValues(), null); myBuilder = new LiveTemplateBuilder(); myEndOffsetMarker = null; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java b/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java index 9269ec6efe8d..38cfe608652a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java @@ -74,7 +74,6 @@ public class LiveTemplateBuilder { last = occurence.myOffset; } template.addTextSegment(myText.substring(last)); - template.setToReformat(true); return template; } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java index 01ffb0dda8a2..11e7a9ebbbbb 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java @@ -304,7 +304,6 @@ class XmlZenCodingInterpreter { return new XmlZenCodingFilterImpl().buildAttributesString(attribute2value, numberInIteration); } - private static void invokeTemplate(TemplateToken token, final CustomTemplateCallback callback, final int numberInIteration, From 4bde984b724782e4b653e0d99342ae2f86fa259b Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Thu, 24 Jun 2010 22:02:56 +0400 Subject: [PATCH 26/36] make some classes public --- .../intellij/codeInsight/template/zencoding/MarkerToken.java | 2 +- .../intellij/codeInsight/template/zencoding/NumberToken.java | 2 +- .../intellij/codeInsight/template/zencoding/OperationToken.java | 2 +- .../src/com/intellij/codeInsight/template/zencoding/Token.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/MarkerToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/MarkerToken.java index 54f54f810c59..490bf3bf4d96 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/MarkerToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/MarkerToken.java @@ -18,7 +18,7 @@ package com.intellij.codeInsight.template.zencoding; /** * @author Eugene.Kudelevsky */ -class MarkerToken extends Token { +public class MarkerToken extends Token { @Override public String toString() { return "&"; diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/NumberToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/NumberToken.java index ffea97d94ac6..466782b080c1 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/NumberToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/NumberToken.java @@ -18,7 +18,7 @@ package com.intellij.codeInsight.template.zencoding; /** * @author Eugene.Kudelevsky */ -class NumberToken extends Token { +public class NumberToken extends Token { private final int myNumber; NumberToken(int number) { diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/OperationToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/OperationToken.java index 1cd3acbd566b..4ba0e23d39c9 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/OperationToken.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/OperationToken.java @@ -18,7 +18,7 @@ package com.intellij.codeInsight.template.zencoding; /** * @author Eugene.Kudelevsky */ -class OperationToken extends Token { +public class OperationToken extends Token { private final char mySign; OperationToken(char sign) { diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/Token.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/Token.java index 082b83bf2f16..3702ced5ff77 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/Token.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/Token.java @@ -18,5 +18,5 @@ package com.intellij.codeInsight.template.zencoding; /** * @author Eugene.Kudelevsky */ -class Token { +public class Token { } From 57433608480b1fbb808cef9e07f22730bc980eaa Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 19:40:44 +0400 Subject: [PATCH 27/36] don't expose LightElement.navigationElement, allow to override it --- .../src/com/intellij/psi/impl/light/LightElement.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/impl/light/LightElement.java b/platform/lang-impl/src/com/intellij/psi/impl/light/LightElement.java index 2dadb49516a1..7d3ab21db6a0 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/light/LightElement.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/light/LightElement.java @@ -33,7 +33,7 @@ import org.jetbrains.annotations.NotNull; public abstract class LightElement extends PsiElementBase { protected final PsiManager myManager; private final Language myLanguage; - protected volatile PsiElement myNavigationElement = this; + private volatile PsiElement myNavigationElement = this; protected LightElement(PsiManager manager, final Language language) { myManager = manager; @@ -97,8 +97,9 @@ public abstract class LightElement extends PsiElementBase { } public boolean isValid() { - if (myNavigationElement != this) { - return myNavigationElement.isValid(); + final PsiElement navElement = getNavigationElement(); + if (navElement != this) { + return navElement.isValid(); } return true; From 304be2a9eed78281d1252e90a08486235ed51448 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 22:19:21 +0400 Subject: [PATCH 28/36] more diagnostics --- .../groovy/compiler/rt/GroovycRunner.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java index d7635078decd..a07d32667bb9 100644 --- a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java +++ b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java @@ -344,17 +344,16 @@ public class GroovycRunner { final ArrayList list = Collections.list(resources); for (Iterator iterator = list.iterator(); iterator.hasNext();) { final URL url = (URL)iterator.next(); - if ("file".equals(url.getProtocol())) { - try { - final String file = new File(new URI(url.toString())).getCanonicalPath(); - System.out.println("Enumerated:" + file); - if (file.startsWith(finalOutput) || file.startsWith("/" + finalOutput)) { - iterator.remove(); - } - } - catch (URISyntaxException ignored) { + try { + final String file = new File(new URI(url.toString())).getCanonicalPath(); + System.out.println("Enumerated:" + file); + if (file.startsWith(finalOutput) || file.startsWith("/" + finalOutput)) { + iterator.remove(); } } + catch (URISyntaxException ignored) { + System.out.println("Invalid URI syntax: " + url.toString()); + } } return Collections.enumeration(list); } From 79bd0b89f85bdf41f30d30fc9f0e11dcbd313f1f Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 24 Jun 2010 21:42:56 +0400 Subject: [PATCH 29/36] fix AsmCodeGeneratorTest in headless environment --- plugins/ui-designer/testData/MethodCallInSuperTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/ui-designer/testData/MethodCallInSuperTest.java b/plugins/ui-designer/testData/MethodCallInSuperTest.java index eaab7412e541..1fc78f1130cd 100644 --- a/plugins/ui-designer/testData/MethodCallInSuperTest.java +++ b/plugins/ui-designer/testData/MethodCallInSuperTest.java @@ -20,7 +20,11 @@ public class MethodCallInSuperTest extends JDialog { private JComponent myRootComponent; public MethodCallInSuperTest() { - super(JOptionPane.getRootFrame(), "", true); + super(getNullFrame(), "", true); getContentPane().add(myRootComponent); } + + private static JFrame getNullFrame() { + return null; + } } \ No newline at end of file From 2c67098373a45dfbf9a656d6f03b08fe6f4f24e7 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 23:06:13 +0400 Subject: [PATCH 30/36] fix more diagnostics --- .../rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java index a07d32667bb9..eafefcc10444 100644 --- a/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java +++ b/plugins/groovy/rt/src/org/jetbrains/groovy/compiler/rt/GroovycRunner.java @@ -351,7 +351,7 @@ public class GroovycRunner { iterator.remove(); } } - catch (URISyntaxException ignored) { + catch (Exception ignored) { System.out.println("Invalid URI syntax: " + url.toString()); } } From f6b3943ec23a936653af779f18639c25c6a53ee0 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 23:24:52 +0400 Subject: [PATCH 31/36] a common supertype for both kinds of groovy method calls --- .../dsl/dsltop/GroovyDslDefaultMembers.java | 11 ++++---- .../groovy/dsl/psi/PsiElementCategory.java | 7 ++--- .../expressions/GrApplicationStatement.java | 9 +++--- .../statements/expressions/GrMethodCall.java | 19 +++++++++++++ .../path/GrMethodCallExpression.java | 5 ++-- .../groovy/lang/psi/impl/PsiImplUtil.java | 28 ++++++++++++------- .../GrApplicationStatementImpl.java | 13 ++++++++- .../path/GrMethodCallExpressionImpl.java | 9 ++---- 8 files changed, 65 insertions(+), 36 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrMethodCall.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/dsltop/GroovyDslDefaultMembers.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/dsltop/GroovyDslDefaultMembers.java index 0bedfa2cf9c3..8cf1d13a619c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/dsltop/GroovyDslDefaultMembers.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/dsltop/GroovyDslDefaultMembers.java @@ -24,9 +24,9 @@ import org.jetbrains.plugins.groovy.dsl.GdslMembersHolderConsumer; import org.jetbrains.plugins.groovy.dsl.holders.DelegatedMembersHolder; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; @@ -147,10 +147,11 @@ public class GroovyDslDefaultMembers implements GdslMembersProvider { @Nullable private static String getInvokedMethodName(GrCall call) { - final GrExpression expr = call instanceof GrApplicationStatement ? ((GrApplicationStatement)call).getFunExpression() : - call instanceof GrMethodCallExpression ? ((GrMethodCallExpression)call).getInvokedExpression() : null; - if (expr instanceof GrReferenceExpression) { - return ((GrReferenceExpression)expr).getName(); + if (call instanceof GrMethodCall) { + final GrExpression expr = ((GrMethodCall)call).getInvokedExpression(); + if (expr instanceof GrReferenceExpression) { + return ((GrReferenceExpression)expr).getName(); + } } return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/psi/PsiElementCategory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/psi/PsiElementCategory.java index 688c56e70d41..d143fe43f046 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/psi/PsiElementCategory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/psi/PsiElementCategory.java @@ -22,10 +22,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import java.util.ArrayList; import java.util.Arrays; @@ -39,9 +38,7 @@ public class PsiElementCategory implements PsiEnhancerCategory { @Nullable public static PsiElement bind(PsiElement element) { - PsiElement elem = element instanceof GrMethodCallExpression ? ((GrMethodCallExpression)element).getInvokedExpression() : - element instanceof GrApplicationStatement ? ((GrApplicationStatement)element).getFunExpression() : - element; + PsiElement elem = element instanceof GrMethodCall ? ((GrMethodCall)element).getInvokedExpression() : element; final PsiReference ref = elem.getReference(); return ref == null ? null : ref.resolve(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrApplicationStatement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrApplicationStatement.java index 84f57f1b024d..1a7eda8cf9ce 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrApplicationStatement.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrApplicationStatement.java @@ -17,17 +17,16 @@ package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; /** * @author ilyas */ -public interface GrApplicationStatement extends GrStatement, GrCall { +public interface GrApplicationStatement extends GrStatement, GrMethodCall { + /** + * @deprecated use {@link GrMethodCall#getInvokedExpression()} + */ GrExpression getFunExpression(); GrExpression[] getArguments(); - GrArgumentList getArgumentList(); - - //PsiElement addNamedArgument(GrNamedArgument argument); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrMethodCall.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrMethodCall.java new file mode 100644 index 000000000000..ceba0b4dca87 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrMethodCall.java @@ -0,0 +1,19 @@ +package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; + +import com.intellij.psi.PsiMethod; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; + +/** + * @author peter + */ +public interface GrMethodCall extends GrCall { + + GrExpression getInvokedExpression(); + + @Nullable + GrArgumentList getArgumentList(); + + @Nullable + PsiMethod resolveMethod(); +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrMethodCallExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrMethodCallExpression.java index a265b0aab1c1..eadb572e0e14 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrMethodCallExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/path/GrMethodCallExpression.java @@ -20,13 +20,12 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; /** * @author ilyas */ -public interface GrMethodCallExpression extends GrCallExpression { - - GrExpression getInvokedExpression(); +public interface GrMethodCallExpression extends GrCallExpression, GrMethodCall { GrExpression replaceClosureArgument(@NotNull GrClosableBlock closure, @NotNull GrExpression newExpr) throws IncorrectOperationException; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java index 5a59d57c2616..c2f07fe0df08 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java @@ -39,7 +39,6 @@ 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.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.arithmetic.*; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.bitwise.GrAndExpressionImpl; @@ -137,18 +136,17 @@ public class PsiImplUtil { if (qualifier == null) { GrClosableBlock closure = PsiTreeUtil.getParentOfType(refExpr, GrClosableBlock.class); while (closure != null) { - GrExpression funExpr = null; PsiElement parent = closure.getParent(); - if (parent instanceof GrApplicationStatement) { - funExpr = ((GrApplicationStatement) parent).getFunExpression(); - } else if (parent instanceof GrMethodCallExpression) { - funExpr = ((GrMethodCallExpression) parent).getInvokedExpression(); + if (parent instanceof GrMethodCall) { + GrExpression funExpr = ((GrMethodCall)parent).getInvokedExpression(); + if (funExpr instanceof GrReferenceExpression) { + qualifier = ((GrReferenceExpression) funExpr).getQualifierExpression(); + if (qualifier != null) { + return qualifier; + } + } } - if (funExpr instanceof GrReferenceExpression) { - qualifier = ((GrReferenceExpression) funExpr).getQualifierExpression(); - if (qualifier != null) break; - } closure = PsiTreeUtil.getParentOfType(closure, GrClosableBlock.class); } @@ -354,4 +352,14 @@ public class PsiImplUtil { return method.getName().equals(MAIN_METHOD) && method.hasModifierProperty(PsiModifier.STATIC); } + + public static PsiMethod resolveMethod(GrMethodCall expression) { + final GrExpression methodExpr = expression.getInvokedExpression(); + if (methodExpr instanceof GrReferenceExpression) { + final PsiElement resolved = ((GrReferenceExpression) methodExpr).resolve(); + return resolved instanceof PsiMethod ? (PsiMethod) resolved : null; + } + + return null; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrApplicationStatementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrApplicationStatementImpl.java index fd7c854956c0..c1f73f65e4da 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrApplicationStatementImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrApplicationStatementImpl.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -26,6 +27,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplic import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCommandArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; /** * @author ilyas @@ -45,7 +47,7 @@ public class GrApplicationStatementImpl extends GrExpressionImpl implements GrAp } public GrExpression getFunExpression() { - return findChildByClass(GrExpression.class); + return getInvokedExpression(); } public GrExpression[] getArguments() { @@ -54,6 +56,15 @@ public class GrApplicationStatementImpl extends GrExpressionImpl implements GrAp return list.getExpressionArguments(); } + public PsiMethod resolveMethod() { + return PsiImplUtil.resolveMethod(this); + } + + @Override + public GrExpression getInvokedExpression() { + return findNotNullChildByClass(GrExpression.class); + } + public GrCommandArgumentList getArgumentList() { return findChildByClass(GrCommandArgumentList.class); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java index e75a7ae082aa..d8011bcaa727 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrMethodCallExpressionImpl.java @@ -35,6 +35,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager; +import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @@ -181,13 +182,7 @@ public class GrMethodCallExpressionImpl extends GrCallExpressionImpl implements } public PsiMethod resolveMethod() { - final GrExpression methodExpr = getInvokedExpression(); - if (methodExpr instanceof GrReferenceExpression) { - final PsiElement resolved = ((GrReferenceExpression) methodExpr).resolve(); - return resolved instanceof PsiMethod ? (PsiMethod) resolved : null; - } - - return null; + return PsiImplUtil.resolveMethod(this); } @NotNull From aaaa1dce5befa9a0bc7487a9743ac25f01738086 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 23:25:08 +0400 Subject: [PATCH 32/36] lazy GrClosureSignature.getReturnType() --- .../impl/types/GrClosureSignatureImpl.java | 34 +++++++++++-------- .../impl/types/GrClosureSignatureUtil.java | 9 +++-- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java index e90e1c37eeaa..00e6099e5cca 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java @@ -19,7 +19,6 @@ import com.intellij.openapi.util.Comparing; import com.intellij.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; @@ -54,14 +53,6 @@ public class GrClosureSignatureImpl implements GrClosureSignature { this(parameters, returnType, PsiSubstitutor.EMPTY); } - public GrClosureSignatureImpl(@NotNull GrClosableBlock block) { - this(block.getAllParameters(), block.getReturnType()); - } - - public GrClosureSignatureImpl(@NotNull PsiMethod method) { - this(method, PsiSubstitutor.EMPTY); - } - public GrClosureSignatureImpl(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor) { this(method.getParameterList().getParameters(), PsiUtil.getSmartReturnType(method), substitutor); } @@ -99,7 +90,7 @@ public class GrClosureSignatureImpl implements GrClosureSignature { public GrClosureSignature curry(int count) { if (count > myParameters.length) { if (isVarargs()) { - return new GrClosureSignatureImpl(GrClosureParameter.EMPTY_ARRAY, myReturnType); + return new DerivedClosureSignature(); } else { return null; @@ -107,22 +98,22 @@ public class GrClosureSignatureImpl implements GrClosureSignature { } GrClosureParameter[] newParams = new GrClosureParameter[myParameters.length - count]; System.arraycopy(myParameters, count, newParams, 0, newParams.length); - return new GrClosureSignatureImpl(newParams, myReturnType, myIsVarargs); + return new DerivedClosureSignature(newParams, null, myIsVarargs); } public boolean isValid() { for (GrClosureParameter parameter : myParameters) { if (!parameter.isValid()) return false; } - return myReturnType == null || myReturnType.isValid(); + final PsiType returnType = getReturnType(); + return returnType == null || returnType.isValid(); } @Override public boolean equals(Object obj) { if (obj instanceof GrClosureSignature) { return Comparing.equal(myParameters, ((GrClosureSignature)obj).getParameters()) && - Comparing.equal(myIsVarargs, ((GrClosureSignature)obj).isVarargs()) && - Comparing.equal(myReturnType, ((GrClosureSignature)obj).getReturnType()); + Comparing.equal(myIsVarargs, ((GrClosureSignature)obj).isVarargs()); } return super.equals(obj); } @@ -152,5 +143,20 @@ public class GrClosureSignatureImpl implements GrClosureSignature { } return null; //todo } + + private class DerivedClosureSignature extends GrClosureSignatureImpl { + DerivedClosureSignature() { + super(GrClosureParameter.EMPTY_ARRAY, null); + } + + DerivedClosureSignature(@NotNull GrClosureParameter[] params, @Nullable PsiType returnType, boolean isVarArgs) { + super(params, returnType, isVarArgs); + } + + @Override + public PsiType getReturnType() { + return GrClosureSignatureImpl.this.getReturnType(); + } + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java index 2f81bd1d5604..8da4feedc7a6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java @@ -48,8 +48,13 @@ public class GrClosureSignatureUtil { private GrClosureSignatureUtil() { } - public static GrClosureSignature createSignature(GrClosableBlock block) { - return new GrClosureSignatureImpl(block); + public static GrClosureSignature createSignature(final GrClosableBlock block) { + return new GrClosureSignatureImpl(block.getAllParameters(), null) { + @Override + public PsiType getReturnType() { + return block.getReturnType(); + } + }; } public static GrClosureSignature createSignature(PsiMethod method, PsiSubstitutor substitutor) { From 4fee3d58f5ea860344fdb9bd997a7840e1079f32 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 23:25:15 +0400 Subject: [PATCH 33/36] resolve packages in groovy files using resolve scope --- .../lang/psi/impl/types/GrCodeReferenceElementImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java index f92c116ed874..90dc803b178a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrCodeReferenceElementImpl.java @@ -292,7 +292,7 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl implement } if (kind == CLASS) return; - PsiPackage[] subpackages = aPackage.getSubPackages(); + PsiPackage[] subpackages = aPackage.getSubPackages(getResolveScope()); for (PsiPackage subpackage : subpackages) { consumer.consume(subpackage); } @@ -385,7 +385,7 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl implement } if (kind == CLASS_OR_PACKAGE) { - for (final PsiPackage subpackage : ((PsiPackage) qualifierResolved).getSubPackages()) { + for (final PsiPackage subpackage : ((PsiPackage) qualifierResolved).getSubPackages(ref.getResolveScope())) { if (refName.equals(subpackage.getName())) return new GroovyResolveResult[]{new GroovyResolveResultImpl(subpackage, true)}; } @@ -410,7 +410,7 @@ public class GrCodeReferenceElementImpl extends GrReferenceElementImpl implement if (kind == CLASS_OR_PACKAGE) { PsiPackage defaultPackage = JavaPsiFacade.getInstance(ref.getProject()).findPackage(""); if (defaultPackage != null) { - for (final PsiPackage subpackage : defaultPackage.getSubPackages()) { + for (final PsiPackage subpackage : defaultPackage.getSubPackages(ref.getResolveScope())) { if (refName.equals(subpackage.getName())) return new GroovyResolveResult[]{new GroovyResolveResultImpl(subpackage, true)}; } From ac1d681f8530bb7ef6006694bfa4ee482d0ec098 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 24 Jun 2010 23:25:24 +0400 Subject: [PATCH 34/36] gant nested elements completion --- plugins/ant/ant.iml | 2 +- .../intellij/lang/ant/dom/AntDomExtender.java | 10 ++-- .../lang/ant/psi/impl/AntIntrospector.java | 2 +- .../plugins/groovy/gant/AntBuilderMethod.java | 59 +++++++++++++++++++ .../plugins/groovy/gant/AntTasksProvider.java | 26 +------- .../groovy/gant/GantMemberContributor.java | 38 +++++++++--- .../GantReferenceCompletionTest.groovy | 23 ++++++++ 7 files changed, 121 insertions(+), 39 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntBuilderMethod.java diff --git a/plugins/ant/ant.iml b/plugins/ant/ant.iml index d0adaec1ca6e..23e5720400f3 100644 --- a/plugins/ant/ant.iml +++ b/plugins/ant/ant.iml @@ -19,7 +19,7 @@ - + diff --git a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java index b3692cb2642e..b64dd2b01b2c 100644 --- a/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java +++ b/plugins/ant/src/com/intellij/lang/ant/dom/AntDomExtender.java @@ -53,13 +53,13 @@ public class AntDomExtender extends DomExtender{ } else { final Map tasks = reflected.getTaskDefinitions(); - final Class taskClass = (Class)tasks.get(tagName); + final Class taskClass = tasks.get(tagName); if (taskClass != null) { parentElementIntrospector = getIntrospector(taskClass); } else { final Map dataTypes = reflected.getDataTypeDefinitions(); - final Class dataClass = (Class)dataTypes.get(tagName); + final Class dataClass = dataTypes.get(tagName); if (dataClass != null) { parentElementIntrospector = getIntrospector(dataClass); } @@ -83,9 +83,9 @@ public class AntDomExtender extends DomExtender{ } } else { - final Enumeration nested = parentElementIntrospector.getNestedElements(); + final Enumeration nested = parentElementIntrospector.getNestedElements(); while (nested.hasMoreElements()) { - registerChild(registrar, genericInfo, (String)nested.nextElement()); + registerChild(registrar, genericInfo, nested.nextElement()); } } } @@ -113,7 +113,7 @@ public class AntDomExtender extends DomExtender{ } @Nullable - private static AntIntrospector getIntrospector(Class c) { + public static AntIntrospector getIntrospector(Class c) { try { return AntIntrospector.getInstance(c); } diff --git a/plugins/ant/src/com/intellij/lang/ant/psi/impl/AntIntrospector.java b/plugins/ant/src/com/intellij/lang/ant/psi/impl/AntIntrospector.java index 596e9cdb6eaf..42acaa1d4454 100644 --- a/plugins/ant/src/com/intellij/lang/ant/psi/impl/AntIntrospector.java +++ b/plugins/ant/src/com/intellij/lang/ant/psi/impl/AntIntrospector.java @@ -99,7 +99,7 @@ public final class AntIntrospector { return types; } - public Enumeration getNestedElements() { + public Enumeration getNestedElements() { return invokeMethod("getNestedElements", false); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntBuilderMethod.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntBuilderMethod.java new file mode 100644 index 000000000000..f569794d0736 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntBuilderMethod.java @@ -0,0 +1,59 @@ +package org.jetbrains.plugins.groovy.gant; + +import com.intellij.lang.ant.dom.AntDomExtender; +import com.intellij.lang.ant.psi.impl.AntIntrospector; +import com.intellij.psi.*; +import com.intellij.psi.impl.light.LightMethodBuilder; +import com.intellij.psi.scope.PsiScopeProcessor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.GroovyFileType; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter; +import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; + +import java.util.Enumeration; + +/** +* @author peter +*/ +class AntBuilderMethod extends LightMethodBuilder { + private final PsiFile myPlace; + @Nullable private final Class myAntClass; + + public AntBuilderMethod(PsiFile place, String name, PsiType closureType, @Nullable Class antClass) { + super(place.getManager(), GroovyFileType.GROOVY_LANGUAGE, name); + myPlace = place; + myAntClass = antClass; + setModifiers(PsiModifier.PUBLIC); + addParameter("args", CommonClassNames.JAVA_UTIL_MAP); + setBaseIcon(GantIcons.ANT_TASK); + addParameter(new GrLightParameter("body", closureType, this).setOptional(true)); + } + + @NotNull + @Override + public PsiElement getNavigationElement() { + if (myAntClass != null) { + final PsiClass psiClass = JavaPsiFacade.getInstance(getProject()).findClass(myAntClass.getName(), myPlace.getResolveScope()); + if (psiClass != null) { + return psiClass; + } + } + return this; + } + + public boolean processNestedElements(PsiScopeProcessor processor) { + final AntIntrospector introspector = AntDomExtender.getIntrospector(myAntClass); + if (introspector != null) { + final Enumeration nested = introspector.getNestedElements(); + while (nested.hasMoreElements()) { + final AntBuilderMethod method = + new AntBuilderMethod(myPlace, nested.nextElement(), getParameterList().getParameters()[1].getType(), null); + if (!ResolveUtil.processElement(processor, method)) { + return false; + } + } + } + return true; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java index b987f4f51a87..8114d61f725b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/AntTasksProvider.java @@ -27,18 +27,15 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.light.LightMethodBuilder; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.util.PsiModificationTracker; import com.intellij.util.PathUtil; import com.intellij.util.lang.UrlClassLoader; -import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.extensions.GroovyScriptType; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; -import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter; import java.net.URL; import java.util.*; @@ -79,29 +76,12 @@ public class AntTasksProvider { final Set result = new HashSet(); final Project project = file.getProject(); - final JavaPsiFacade facade = JavaPsiFacade.getInstance(project); - final GlobalSearchScope scope = file.getResolveScope(); - - final PsiType closureType = JavaPsiFacade.getElementFactory(project).createTypeFromText(GrClosableBlock.GROOVY_LANG_CLOSURE, - file); + final PsiType closureType = JavaPsiFacade.getElementFactory(project).createTypeFromText(GrClosableBlock.GROOVY_LANG_CLOSURE, file); for (String name : antObjects.keySet()) { - final PsiClass psiClass = facade.findClass(antObjects.get(name).getName(), scope); - - final LightMethodBuilder tdMethod = - new LightMethodBuilder(PsiManager.getInstance(project), GroovyFileType.GROOVY_LANGUAGE, name). - setModifiers(PsiModifier.PUBLIC). - addParameter("args", CommonClassNames.JAVA_UTIL_MAP). - setBaseIcon(GantIcons.ANT_TASK); - - tdMethod.addParameter(new GrLightParameter("body", closureType, tdMethod).setOptional(true)); - - if (psiClass != null) { - tdMethod.setNavigationElement(psiClass); - } - result.add(tdMethod); + result.add(new AntBuilderMethod(file, name, closureType, antObjects.get(name))); } - return Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, ProjectRootManager.getInstance(file.getProject())); + return Result.create(result, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, ProjectRootManager.getInstance(project)); } }, false); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantMemberContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantMemberContributor.java index ed8162023a2b..205a067e9945 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantMemberContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/gant/GantMemberContributor.java @@ -15,10 +15,7 @@ */ package org.jetbrains.plugins.groovy.gant; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiNamedElement; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; import com.intellij.psi.impl.light.LightMethodBuilder; import com.intellij.psi.impl.light.LightVariableBuilder; import com.intellij.psi.scope.PsiScopeProcessor; @@ -26,6 +23,7 @@ import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersProcessor; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; @@ -45,13 +43,35 @@ public class GantMemberContributor implements NonCodeMembersProcessor { return true; } - PsiFile file = place.getContainingFile(); - if (!GantUtils.isGantScriptFile(file)) { + GrClosableBlock closure = PsiTreeUtil.getContextOfType(place, GrClosableBlock.class, true); + if (closure == null) { return true; } - final GrClosableBlock closure = PsiTreeUtil.getContextOfType(place, GrClosableBlock.class, true); - if (closure == null) { + boolean antTasksProcessed = false; + while (closure != null) { + final PsiElement parent = closure.getParent(); + if (parent instanceof GrMethodCall) { + final PsiMethod method = ((GrMethodCall)parent).resolveMethod(); + if (method instanceof AntBuilderMethod) { + antTasksProcessed = true; + if (!processAntTasks(processor, place)) { + return false; + } + if (!((AntBuilderMethod)method).processNestedElements(processor)) { + return false; + } + break; + } + } + + closure = PsiTreeUtil.getContextOfType(closure, GrClosableBlock.class, true); + } + + // ------- gant-specific + + PsiFile file = place.getContainingFile(); + if (!GantUtils.isGantScriptFile(file)) { return true; } @@ -66,7 +86,7 @@ public class GantMemberContributor implements NonCodeMembersProcessor { } } - return processAntTasks(processor, place); + return antTasksProcessed || processAntTasks(processor, place); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/GantReferenceCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/GantReferenceCompletionTest.groovy index e2bd83205322..4dad2bc7c506 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/GantReferenceCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/GantReferenceCompletionTest.groovy @@ -106,6 +106,29 @@ def foo() { checkVariants "ant.pattt", "patternset" } + public void testTagsInsideTags() throws Exception { + myFixture.configureByText "a.groovy", """ +AntBuilder ant +ant.zip { + patternset { + includ + } +}""" + myFixture.completeBasic() + assertSameElements myFixture.lookupElementStrings, "include", "includesfile" + } + + public void testTagsInsideTagsInGantTarget() throws Exception { + checkVariants """ +target(aaa: "") { + zip { + patternset { + includ + } + } +}""", "include", "includesfile", "includeTargets", "includeTool" + } + static final def GANT_JARS = ["gant.jar", "ant.jar", "ant-junit.jar", "ant-launcher.jar", "commons.jar"] } From 47f89c9c0dd647db83d96ac07439fd8f3204ed45 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 25 Jun 2010 00:54:57 +0400 Subject: [PATCH 35/36] gant completion when gant is not in project's classpath --- .../groovy/dsl/CustomMembersGenerator.groovy | 2 +- .../dsl/holders/NonCodeMembersHolder.java | 17 +++--- .../groovy/lang/psi/impl/GroovyFileImpl.java | 5 ++ .../GantReferenceCompletionTest.groovy | 2 +- .../StandaloneGantCompletionTest.groovy | 53 ++++++++++++++++++ .../mockGantLib/{ => lib}/ant-junit.jar | Bin .../mockGantLib/{ => lib}/ant-launcher.jar | Bin .../testdata/mockGantLib/{ => lib}/ant.jar | Bin .../mockGantLib/{ => lib}/commons.jar | Bin .../testdata/mockGantLib/{ => lib}/gant.jar | Bin 10 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/StandaloneGantCompletionTest.groovy rename plugins/groovy/testdata/mockGantLib/{ => lib}/ant-junit.jar (100%) rename plugins/groovy/testdata/mockGantLib/{ => lib}/ant-launcher.jar (100%) rename plugins/groovy/testdata/mockGantLib/{ => lib}/ant.jar (100%) rename plugins/groovy/testdata/mockGantLib/{ => lib}/commons.jar (100%) rename plugins/groovy/testdata/mockGantLib/{ => lib}/gant.jar (100%) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.groovy b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.groovy index 994cb82d621b..6ceef5674a7f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.groovy +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/CustomMembersGenerator.groovy @@ -77,7 +77,7 @@ public class CustomMembersGenerator implements GdslMembersHolderConsumer { public CustomMembersHolder getMembersHolder() { // Add non-code members holder if (myClassText.length() > 0) { - addMemberHolder(NonCodeMembersHolder.fromText(myClassText.toString(), myProject)); + addMemberHolder(NonCodeMembersHolder.fromText(myClassText.toString(), myPlace.containingFile)); } return myDepot; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/holders/NonCodeMembersHolder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/holders/NonCodeMembersHolder.java index 4b4c87f2e268..7589019d05f8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/holders/NonCodeMembersHolder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/holders/NonCodeMembersHolder.java @@ -15,11 +15,8 @@ */ package org.jetbrains.plugins.groovy.dsl.holders; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.ResolveState; +import com.intellij.psi.*; import com.intellij.psi.scope.NameHint; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.CachedValue; @@ -38,13 +35,13 @@ public class NonCodeMembersHolder implements CustomMembersHolder { private final GrTypeDefinition myPsiClass; private static final Key>> CACHED_HOLDERS = Key.create("CACHED_HOLDERS"); - public static NonCodeMembersHolder fromText(@NotNull String classText, final Project project) { - return CachedValuesManager.getManager(project).getCachedValue(project, CACHED_HOLDERS, new CachedValueProvider>() { + public static NonCodeMembersHolder fromText(@NotNull String classText, final PsiFile place) { + return CachedValuesManager.getManager(place.getProject()).getCachedValue(place, CACHED_HOLDERS, new CachedValueProvider>() { public Result> compute() { final ConcurrentFactoryMap map = new ConcurrentFactoryMap() { @Override protected NonCodeMembersHolder create(String key) { - return new NonCodeMembersHolder(key, project); + return new NonCodeMembersHolder(key, place); } }; return Result.create(map, PsiModificationTracker.MODIFICATION_COUNT); @@ -52,9 +49,9 @@ public class NonCodeMembersHolder implements CustomMembersHolder { }, false).get(classText); } - private NonCodeMembersHolder(@NotNull String classText, Project project) { - final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project); - myPsiClass = factory.createGroovyFile("class GroovyEnhanced {\n" + classText + "}", false, null).getTypeDefinitions()[0]; + private NonCodeMembersHolder(@NotNull String classText, PsiElement place) { + final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(place.getProject()); + myPsiClass = factory.createGroovyFile("class GroovyEnhanced {\n" + classText + "}", false, place).getTypeDefinitions()[0]; } public boolean processMembers(PsiScopeProcessor processor) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java index c414d89f5738..6d26504ca5ea 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java @@ -468,6 +468,11 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { } }; public GlobalSearchScope getFileResolveScope() { + final PsiElement context = getContext(); + if (context instanceof GroovyFile) { + return context.getResolveScope(); + } + final VirtualFile vFile = getOriginalFile().getVirtualFile(); if (vFile == null) { return GlobalSearchScope.allScope(getProject()); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/GantReferenceCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/GantReferenceCompletionTest.groovy index 4dad2bc7c506..59c3f88f87f9 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/GantReferenceCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/GantReferenceCompletionTest.groovy @@ -149,7 +149,7 @@ class GantProjectDescriptor implements LightProjectDescriptor { modifiableModel.addRoot(fs.findFileByPath("$TestUtils.mockGroovyLibraryHome/$TestUtils.GROOVY_JAR!/"), OrderRootType.CLASSES); GantReferenceCompletionTest.GANT_JARS.each { - modifiableModel.addRoot(fs.findFileByPath("${TestUtils.absoluteTestDataPath}mockGantLib/$it!/"), OrderRootType.CLASSES); + modifiableModel.addRoot(fs.findFileByPath("${TestUtils.absoluteTestDataPath}mockGantLib/lib/$it!/"), OrderRootType.CLASSES); } modifiableModel.commit(); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/StandaloneGantCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/StandaloneGantCompletionTest.groovy new file mode 100644 index 000000000000..e551897ab51e --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/gant/completion/StandaloneGantCompletionTest.groovy @@ -0,0 +1,53 @@ +package org.jetbrains.plugins.groovy.gant.completion; + + +import com.intellij.openapi.util.io.FileUtil +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.plugins.groovy.gant.GantSettings +import org.jetbrains.plugins.groovy.util.SdkHomeConfigurable.SdkHomeBean +import org.jetbrains.plugins.groovy.util.TestUtils + +/** + * @author peter + */ +public class StandaloneGantCompletionTest extends LightCodeInsightFixtureTestCase { + + @Override + protected String getBasePath() { + return TestUtils.getTestDataPath() + "gant/completion"; + } + + @Override protected void setUp() { + super.setUp(); + final SdkHomeBean state = new SdkHomeBean(); + state.SDK_HOME = FileUtil.toSystemIndependentName("${TestUtils.absoluteTestDataPath}mockGantLib"); + GantSettings.getInstance(getProject()).loadState state + } + + @Override protected void tearDown() { + GantSettings.getInstance(getProject()).loadState new SdkHomeBean() + super.tearDown(); + } + + void checkVariants(String text, String... items) { + myFixture.configureByText "a.gant", text + myFixture.completeBasic() + assertSameElements myFixture.lookupElementStrings, items + } + + public void testDep() throws Throwable { + checkVariants """ +target(aaa: "") { + dep +} +""", "depends", "dependset" + } + + public void testPatternset() throws Exception { + checkVariants "ant.pattt", "patternset" + } + + static final def GANT_JARS = ["gant.jar", "ant.jar", "ant-junit.jar", "ant-launcher.jar", "commons.jar"] + +} + diff --git a/plugins/groovy/testdata/mockGantLib/ant-junit.jar b/plugins/groovy/testdata/mockGantLib/lib/ant-junit.jar similarity index 100% rename from plugins/groovy/testdata/mockGantLib/ant-junit.jar rename to plugins/groovy/testdata/mockGantLib/lib/ant-junit.jar diff --git a/plugins/groovy/testdata/mockGantLib/ant-launcher.jar b/plugins/groovy/testdata/mockGantLib/lib/ant-launcher.jar similarity index 100% rename from plugins/groovy/testdata/mockGantLib/ant-launcher.jar rename to plugins/groovy/testdata/mockGantLib/lib/ant-launcher.jar diff --git a/plugins/groovy/testdata/mockGantLib/ant.jar b/plugins/groovy/testdata/mockGantLib/lib/ant.jar similarity index 100% rename from plugins/groovy/testdata/mockGantLib/ant.jar rename to plugins/groovy/testdata/mockGantLib/lib/ant.jar diff --git a/plugins/groovy/testdata/mockGantLib/commons.jar b/plugins/groovy/testdata/mockGantLib/lib/commons.jar similarity index 100% rename from plugins/groovy/testdata/mockGantLib/commons.jar rename to plugins/groovy/testdata/mockGantLib/lib/commons.jar diff --git a/plugins/groovy/testdata/mockGantLib/gant.jar b/plugins/groovy/testdata/mockGantLib/lib/gant.jar similarity index 100% rename from plugins/groovy/testdata/mockGantLib/gant.jar rename to plugins/groovy/testdata/mockGantLib/lib/gant.jar From 4e9206b9b5683f2002a1828b2a81758c71e46d2d Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 25 Jun 2010 00:55:19 +0400 Subject: [PATCH 36/36] even lazier GrClosureSignature.returnType --- .../lang/psi/impl/types/GrClosureSignatureImpl.java | 4 ---- .../lang/psi/impl/types/GrClosureSignatureUtil.java | 10 ++++++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java index 00e6099e5cca..c6fd2f5b186f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureImpl.java @@ -53,10 +53,6 @@ public class GrClosureSignatureImpl implements GrClosureSignature { this(parameters, returnType, PsiSubstitutor.EMPTY); } - public GrClosureSignatureImpl(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor) { - this(method.getParameterList().getParameters(), PsiUtil.getSmartReturnType(method), substitutor); - } - GrClosureSignatureImpl(@NotNull GrClosureParameter[] params, @Nullable PsiType returnType, boolean isVarArgs) { myParameters = params; myReturnType = returnType; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java index 8da4feedc7a6..0d47ff121f71 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrClosureSignatureUtil.java @@ -35,6 +35,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature; import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.ArrayList; import java.util.Arrays; @@ -57,8 +58,13 @@ public class GrClosureSignatureUtil { }; } - public static GrClosureSignature createSignature(PsiMethod method, PsiSubstitutor substitutor) { - return new GrClosureSignatureImpl(method, substitutor); + public static GrClosureSignature createSignature(final PsiMethod method, PsiSubstitutor substitutor) { + return new GrClosureSignatureImpl(method.getParameterList().getParameters(), null, substitutor) { + @Override + public PsiType getReturnType() { + return PsiUtil.getSmartReturnType(method); + } + }; } public static GrClosureSignature createSignature(PsiParameter[] parameters, PsiType returnType) {