mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
Merge commit 'c667235951b68017e427bc7a9d9f6dd2b60a9d35' into HEAD
This commit is contained in:
@@ -27,9 +27,8 @@ public class SuspendManagerUtil {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.SuspendManagerUtil");
|
||||
|
||||
public static boolean isEvaluating(SuspendManager suspendManager, ThreadReferenceProxyImpl thread) {
|
||||
for (Iterator<SuspendContextImpl> iterator = ((SuspendManagerImpl) suspendManager).getEventContexts().iterator(); iterator.hasNext();) {
|
||||
SuspendContextImpl suspendContext = iterator.next();
|
||||
if(suspendContext.isEvaluating() && thread.equals(suspendContext.getThread())) {
|
||||
for (SuspendContextImpl suspendContext : suspendManager.getEventContexts()) {
|
||||
if (suspendContext.isEvaluating() && thread.equals(suspendContext.getThread())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -121,8 +120,8 @@ public class SuspendManagerUtil {
|
||||
}
|
||||
|
||||
public static SuspendContextImpl getEvaluatingContext(SuspendManager suspendManager, ThreadReferenceProxyImpl thread) {
|
||||
for (SuspendContextImpl suspendContext : ((SuspendManagerImpl)suspendManager).getEventContexts()) {
|
||||
if (suspendContext.isEvaluating() && suspendContext.getThread() == thread) {
|
||||
for (SuspendContextImpl suspendContext : suspendManager.getEventContexts()) {
|
||||
if (!suspendContext.isResumed() && suspendContext.isEvaluating() && suspendContext.getThread() == thread) {
|
||||
return suspendContext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,7 +154,8 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
|
||||
return getStackFrame().location();
|
||||
}
|
||||
catch (InvalidStackFrameException e) {
|
||||
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.thread.resumed"), e);
|
||||
clearCaches();
|
||||
return location();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -98,6 +98,7 @@ public class CreateNewLibraryAction extends AnAction {
|
||||
private void appendLibraryToModules(final ModuleStructureConfigurable rootConfigurable, final Library libraryToSelect) {
|
||||
final List<Module> modules = new ArrayList<Module>();
|
||||
ContainerUtil.addAll(modules, rootConfigurable.getModules());
|
||||
if (modules.isEmpty()) return;
|
||||
final ChooseModulesDialog dlg = new ChooseModulesDialog(myProject,
|
||||
modules, ProjectBundle.message("choose.modules.dialog.title"),
|
||||
ProjectBundle
|
||||
|
||||
@@ -219,7 +219,7 @@ public class CodeInsightUtil {
|
||||
public static boolean areExpressionsEquivalent(PsiExpression expr1, PsiExpression expr2) {
|
||||
return PsiEquivalenceUtil.areElementsEquivalent(expr1, expr2, new Comparator<PsiElement>() {
|
||||
public int compare(PsiElement o1, PsiElement o2) {
|
||||
if (o1 instanceof PsiParameter && o2 instanceof PsiParameter) {
|
||||
if (o1 instanceof PsiParameter && o2 instanceof PsiParameter && ((PsiParameter)o1).getDeclarationScope() instanceof PsiMethod) {
|
||||
return ((PsiParameter)o1).getName().compareTo(((PsiParameter)o2).getName());
|
||||
}
|
||||
return 1;
|
||||
|
||||
+22
-1
@@ -238,6 +238,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction {
|
||||
}
|
||||
int ei = 0;
|
||||
int pi = 0;
|
||||
PsiParameter varargParam = targetMethod.isVarArgs() ? parameters[parameters.length - 1] : null;
|
||||
while (ei < expressions.length || pi < parameters.length) {
|
||||
PsiExpression expression = ei < expressions.length ? expressions[ei] : null;
|
||||
PsiParameter parameter = pi < parameters.length ? parameters[pi] : null;
|
||||
@@ -248,7 +249,16 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction {
|
||||
pi++;
|
||||
ei++;
|
||||
}
|
||||
else if (isArgumentInVarargPosition(expressions, ei, varargParam, substitutor)) {
|
||||
if (pi == parameters.length - 1) {
|
||||
assert varargParam != null;
|
||||
result.add(new ParameterInfoImpl(pi, varargParam.getName(), varargParam.getType()));
|
||||
}
|
||||
pi++;
|
||||
ei++;
|
||||
}
|
||||
else if (expression != null) {
|
||||
if (varargParam != null && pi >= parameters.length) return null;
|
||||
PsiType exprType = RefactoringUtil.getTypeByExpression(expression);
|
||||
if (exprType == null) return null;
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(expression.getProject());
|
||||
@@ -257,7 +267,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction {
|
||||
ei++;
|
||||
}
|
||||
}
|
||||
if (result.size() != expressions.length) return null;
|
||||
if (result.size() != expressions.length && varargParam == null) return null;
|
||||
}
|
||||
else {
|
||||
//parameter type changed
|
||||
@@ -291,6 +301,17 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction {
|
||||
return result.toArray(new ParameterInfoImpl[result.size()]);
|
||||
}
|
||||
|
||||
private static boolean isArgumentInVarargPosition(PsiExpression[] expressions, int ei, PsiParameter varargParam, PsiSubstitutor substitutor) {
|
||||
if (varargParam == null) return false;
|
||||
final PsiExpression expression = expressions[ei];
|
||||
if (expression == null || TypeConversionUtil.areTypesAssignmentCompatible(substitutor.substitute(((PsiEllipsisType)varargParam.getType()).getComponentType()), expression)) {
|
||||
final int lastExprIdx = expressions.length - 1;
|
||||
if (ei == lastExprIdx) return true;
|
||||
return expressions[lastExprIdx].getType() != PsiType.NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String suggestUniqueParameterName(JavaCodeStyleManager codeStyleManager,
|
||||
PsiExpression expression,
|
||||
PsiType exprType,
|
||||
|
||||
@@ -40,14 +40,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author max
|
||||
*/
|
||||
public class JavaParserDefinition implements ParserDefinition {
|
||||
public static final boolean USE_NEW_PARSER = false;
|
||||
|
||||
@NotNull
|
||||
public Lexer createLexer(Project project) {
|
||||
return new JavaLexer(LanguageLevelProjectExtension.getInstance(project).getLanguageLevel());
|
||||
public Lexer createLexer(final Project project) {
|
||||
final LanguageLevel languageLevel = LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
|
||||
return createLexer(languageLevel);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Lexer createLexer(LanguageLevel languageLevel) {
|
||||
public static Lexer createLexer(final LanguageLevel languageLevel) {
|
||||
return new JavaLexer(languageLevel);
|
||||
}
|
||||
|
||||
@@ -72,11 +74,11 @@ public class JavaParserDefinition implements ParserDefinition {
|
||||
|
||||
@NotNull
|
||||
public PsiParser createParser(final Project project) {
|
||||
return PsiUtil.NULL_PARSER;
|
||||
throw new UnsupportedOperationException("Should not be called directly");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement createElement(ASTNode node) {
|
||||
public PsiElement createElement(final ASTNode node) {
|
||||
final IElementType type = node.getElementType();
|
||||
if (type instanceof JavaStubElementType) {
|
||||
return ((JavaStubElementType)type).createPsi(node);
|
||||
@@ -85,7 +87,7 @@ public class JavaParserDefinition implements ParserDefinition {
|
||||
return PsiUtil.NULL_PSI_ELEMENT;
|
||||
}
|
||||
|
||||
public PsiFile createFile(FileViewProvider viewProvider) {
|
||||
public PsiFile createFile(final FileViewProvider viewProvider) {
|
||||
return new PsiJavaFileImpl(viewProvider);
|
||||
}
|
||||
|
||||
|
||||
@@ -172,7 +172,6 @@ public class JavaParserUtil {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ASTNode parseFragment(final ASTNode chameleon, final ParserWrapper wrapper) {
|
||||
final PsiElement psi = (chameleon.getTreeParent() != null ? chameleon.getTreeParent().getPsi() : chameleon.getPsi());
|
||||
assert psi != null : chameleon;
|
||||
|
||||
@@ -22,30 +22,31 @@ package com.intellij.psi.impl.java.stubs;
|
||||
import com.intellij.psi.impl.source.JavaFileElementType;
|
||||
import com.intellij.psi.tree.IStubFileElementType;
|
||||
|
||||
public class JavaStubElementTypes {
|
||||
public static final JavaClassElementType CLASS = new JavaClassElementType("CLASS");
|
||||
public static final JavaClassElementType ANONYMOUS_CLASS = new JavaClassElementType("ANONYMOUS_CLASS");
|
||||
public static final JavaClassElementType ENUM_CONSTANT_INITIALIZER = new JavaClassElementType("ENUM_CONSTANT_INITIALIZER");
|
||||
public interface JavaStubElementTypes {
|
||||
JavaClassElementType CLASS = new JavaClassElementType("CLASS");
|
||||
JavaClassElementType ANONYMOUS_CLASS = new JavaClassElementType("ANONYMOUS_CLASS");
|
||||
JavaClassElementType ENUM_CONSTANT_INITIALIZER = new JavaClassElementType("ENUM_CONSTANT_INITIALIZER");
|
||||
|
||||
public static final JavaModifierListElementType MODIFIER_LIST = new JavaModifierListElementType();
|
||||
public static final JavaMethodElementType METHOD = new JavaMethodElementType("METHOD");
|
||||
public static final JavaMethodElementType ANNOTATION_METHOD = new JavaMethodElementType("ANNOTATION_METHOD");
|
||||
public static final JavaFieldStubElementType FIELD = new JavaFieldStubElementType("FIELD");
|
||||
public static final JavaFieldStubElementType ENUM_CONSTANT = new JavaFieldStubElementType("ENUM_CONSTANT");
|
||||
JavaModifierListElementType MODIFIER_LIST = new JavaModifierListElementType();
|
||||
JavaMethodElementType METHOD = new JavaMethodElementType("METHOD");
|
||||
JavaMethodElementType ANNOTATION_METHOD = new JavaMethodElementType("ANNOTATION_METHOD");
|
||||
JavaFieldStubElementType FIELD = new JavaFieldStubElementType("FIELD");
|
||||
JavaFieldStubElementType ENUM_CONSTANT = new JavaFieldStubElementType("ENUM_CONSTANT");
|
||||
|
||||
public static final JavaAnnotationElementType ANNOTATION = new JavaAnnotationElementType();
|
||||
public static final JavaClassReferenceListElementType EXTENDS_LIST = new JavaClassReferenceListElementType("EXTENDS_LIST");
|
||||
public static final JavaClassReferenceListElementType IMPLEMENTS_LIST = new JavaClassReferenceListElementType("IMPLEMENTS_LIST");
|
||||
public static final JavaClassReferenceListElementType THROWS_LIST = new JavaClassReferenceListElementType("THROWS_LIST");
|
||||
public static final JavaClassReferenceListElementType EXTENDS_BOUND_LIST = new JavaClassReferenceListElementType("EXTENDS_BOUND_LIST");
|
||||
JavaAnnotationElementType ANNOTATION = new JavaAnnotationElementType();
|
||||
JavaClassReferenceListElementType EXTENDS_LIST = new JavaClassReferenceListElementType("EXTENDS_LIST");
|
||||
JavaClassReferenceListElementType IMPLEMENTS_LIST = new JavaClassReferenceListElementType("IMPLEMENTS_LIST");
|
||||
JavaClassReferenceListElementType THROWS_LIST = new JavaClassReferenceListElementType("THROWS_LIST");
|
||||
JavaClassReferenceListElementType EXTENDS_BOUND_LIST = new JavaClassReferenceListElementType("EXTENDS_BOUND_LIST");
|
||||
|
||||
public static final JavaParameterElementType PARAMETER = new JavaParameterElementType();
|
||||
public static final JavaParameterListElementType PARAMETER_LIST = new JavaParameterListElementType();
|
||||
public static final JavaTypeParameterElementType TYPE_PARAMETER = new JavaTypeParameterElementType();
|
||||
public static final JavaTypeParameterListElementType TYPE_PARAMETER_LIST = new JavaTypeParameterListElementType();
|
||||
public static final JavaClassInitializerElementType CLASS_INITIALIZER = new JavaClassInitializerElementType();
|
||||
public static final JavaImportListElementType IMPORT_LIST = new JavaImportListElementType();
|
||||
public static final JavaImportStatementElementType IMPORT_STATEMENT = new JavaImportStatementElementType("IMPORT_STATEMENT");
|
||||
public static final JavaImportStatementElementType IMPORT_STATIC_STATEMENT = new JavaImportStatementElementType("IMPORT_STATIC_STATEMENT");
|
||||
public static final IStubFileElementType JAVA_FILE = new JavaFileElementType();
|
||||
JavaParameterElementType PARAMETER = new JavaParameterElementType();
|
||||
JavaParameterListElementType PARAMETER_LIST = new JavaParameterListElementType();
|
||||
JavaTypeParameterElementType TYPE_PARAMETER = new JavaTypeParameterElementType();
|
||||
JavaTypeParameterListElementType TYPE_PARAMETER_LIST = new JavaTypeParameterListElementType();
|
||||
JavaClassInitializerElementType CLASS_INITIALIZER = new JavaClassInitializerElementType();
|
||||
JavaImportListElementType IMPORT_LIST = new JavaImportListElementType();
|
||||
JavaImportStatementElementType IMPORT_STATEMENT = new JavaImportStatementElementType("IMPORT_STATEMENT");
|
||||
JavaImportStatementElementType IMPORT_STATIC_STATEMENT = new JavaImportStatementElementType("IMPORT_STATIC_STATEMENT");
|
||||
|
||||
IStubFileElementType JAVA_FILE = new JavaFileElementType();
|
||||
}
|
||||
+1
-1
@@ -34,7 +34,7 @@ import java.io.IOException;
|
||||
|
||||
public class JavaTypeParameterElementType extends JavaStubElementType<PsiTypeParameterStub, PsiTypeParameter> {
|
||||
public JavaTypeParameterElementType() {
|
||||
super("TYPE_PARAMETR");
|
||||
super("TYPE_PARAMETER");
|
||||
}
|
||||
|
||||
public PsiTypeParameter createPsi(final PsiTypeParameterStub stub) {
|
||||
|
||||
@@ -20,7 +20,11 @@
|
||||
package com.intellij.psi.impl.source;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.lang.java.parser.FileParser;
|
||||
import com.intellij.lang.java.parser.JavaParserUtil;
|
||||
import com.intellij.lexer.JavaLexer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -41,7 +45,7 @@ import com.intellij.util.io.StringRef;
|
||||
import java.io.IOException;
|
||||
|
||||
public class JavaFileElementType extends IStubFileElementType<PsiJavaFileStub> {
|
||||
public static final int STUB_VERSION = 3;
|
||||
public static final int STUB_VERSION = JavaParserDefinition.USE_NEW_PARSER ? 4 : 3;
|
||||
|
||||
public JavaFileElementType() {
|
||||
super("java.FILE", StdLanguages.JAVA);
|
||||
@@ -61,7 +65,17 @@ public class JavaFileElementType extends IStubFileElementType<PsiJavaFileStub> {
|
||||
return dir == null || dir.getUserData(LanguageLevel.KEY) != null;
|
||||
}
|
||||
|
||||
public ASTNode parseContents(ASTNode chameleon) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
final PsiBuilder builder = JavaParserUtil.createBuilder(chameleon);
|
||||
|
||||
final PsiBuilder.Marker root = builder.mark();
|
||||
FileParser.parse(builder);
|
||||
root.done(this);
|
||||
|
||||
return builder.getTreeBuilt().getFirstChildNode();
|
||||
}
|
||||
|
||||
FileElement node = (FileElement)chameleon;
|
||||
final CharSequence seq = node.getChars();
|
||||
|
||||
|
||||
@@ -15,8 +15,12 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.tree;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.lang.java.parser.ExpressionParser;
|
||||
import com.intellij.lang.java.parser.JavaParserUtil;
|
||||
import com.intellij.lang.java.parser.ReferenceParser;
|
||||
import com.intellij.lang.java.parser.StatementParser;
|
||||
import com.intellij.lexer.JavaLexer;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -31,12 +35,13 @@ import com.intellij.psi.text.BlockSupport;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IErrorCounterReparseableElementType;
|
||||
import com.intellij.psi.tree.ILazyParseableElementType;
|
||||
import com.intellij.psi.tree.ILightLazyParseableElementType;
|
||||
import com.intellij.psi.tree.java.IJavaElementType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.CharTable;
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure;
|
||||
|
||||
public interface JavaElementType {
|
||||
|
||||
IElementType CLASS = JavaStubElementTypes.CLASS;
|
||||
IElementType ANONYMOUS_CLASS = JavaStubElementTypes.ANONYMOUS_CLASS;
|
||||
IElementType ENUM_CONSTANT_INITIALIZER = JavaStubElementTypes.ENUM_CONSTANT_INITIALIZER;
|
||||
@@ -120,13 +125,24 @@ public interface JavaElementType {
|
||||
IElementType ANNOTATION_PARAMETER_LIST = new IJavaElementType("ANNOTATION_PARAMETER_LIST", true);
|
||||
IElementType METHOD_RECEIVER = new IJavaElementType("METHOD_RECEIVER");
|
||||
|
||||
ILazyParseableElementType CODE_BLOCK = new IErrorCounterReparseableElementType("CODE_BLOCK", StdLanguages.JAVA) {
|
||||
class ICodeBlockElementType extends IErrorCounterReparseableElementType {
|
||||
private ICodeBlockElementType() {
|
||||
super("CODE_BLOCK", StdLanguages.JAVA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode createNode(CharSequence text) {
|
||||
public ASTNode createNode(final CharSequence text) {
|
||||
return new PsiCodeBlockImpl(text);
|
||||
}
|
||||
|
||||
public ASTNode parseContents(ASTNode chameleon) {
|
||||
@Override
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
final PsiBuilder builder = JavaParserUtil.createBuilder(chameleon);
|
||||
StatementParser.parseCodeBlockDeep(builder, true);
|
||||
return builder.getTreeBuilt().getFirstChildNode();
|
||||
}
|
||||
|
||||
final CharSequence seq = chameleon.getChars();
|
||||
|
||||
ASTNode original = chameleon.getUserData(BlockSupport.TREE_TO_BE_REPARSED);
|
||||
@@ -137,20 +153,20 @@ public interface JavaElementType {
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(TreeUtil.getFileElement((TreeElement)context).getPsi());
|
||||
JavaParsingContext parsingContext = new JavaParsingContext(table, languageLevel);
|
||||
return parsingContext.getStatementParsing().parseCodeBlockText(manager, new JavaLexer(languageLevel),
|
||||
seq, 0, seq.length(), 0).getFirstChildNode();
|
||||
seq, 0, seq.length(), 0).getFirstChildNode();
|
||||
}
|
||||
|
||||
public int getErrorsCount(CharSequence seq, Project project) {
|
||||
public int getErrorsCount(final CharSequence seq, final Project project) {
|
||||
final Lexer lexer = new JavaLexer(LanguageLevel.HIGHEST);
|
||||
|
||||
lexer.start(seq);
|
||||
if(lexer.getTokenType() != JavaTokenType.LBRACE) return FATAL_ERROR;
|
||||
if (lexer.getTokenType() != JavaTokenType.LBRACE) return FATAL_ERROR;
|
||||
lexer.advance();
|
||||
int balance = 1;
|
||||
while(true){
|
||||
while (true) {
|
||||
IElementType type = lexer.getTokenType();
|
||||
if (type == null) break;
|
||||
if(balance == 0) return FATAL_ERROR;
|
||||
if (balance == 0) return FATAL_ERROR;
|
||||
if (type == JavaTokenType.LBRACE) {
|
||||
balance++;
|
||||
}
|
||||
@@ -161,11 +177,29 @@ public interface JavaElementType {
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class ICodeBlockNewElementType extends ICodeBlockElementType implements ILightLazyParseableElementType {
|
||||
public FlyweightCapableTreeStructure<LighterASTNode> parseContents(final LighterLazyParseableNode chameleon) {
|
||||
final PsiBuilder builder = JavaParserUtil.createBuilder(chameleon);
|
||||
StatementParser.parseCodeBlockDeep(builder, true);
|
||||
return builder.getLightTree();
|
||||
}
|
||||
}
|
||||
|
||||
ILazyParseableElementType CODE_BLOCK = JavaParserDefinition.USE_NEW_PARSER ? new ICodeBlockNewElementType() : new ICodeBlockElementType();
|
||||
|
||||
IElementType STATEMENTS = new ICodeFragmentElementType("STATEMENTS", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
StatementParser.parseStatements(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//The following are the children of code fragment
|
||||
IElementType STATEMENTS = new ICodeFragmentElementType("STATEMENTS", StdLanguages.JAVA){
|
||||
public ASTNode parseContents(ASTNode chameleon) {
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
final PsiManager manager = ((FileElement)chameleon).getManager();
|
||||
final CharTable table = SharedImplUtil.findCharTableByTree(chameleon);
|
||||
@@ -174,8 +208,17 @@ public interface JavaElementType {
|
||||
}
|
||||
};
|
||||
|
||||
IElementType EXPRESSION_TEXT = new ICodeFragmentElementType("EXPRESSION_TEXT", StdLanguages.JAVA){
|
||||
public ASTNode parseContents(ASTNode chameleon) {
|
||||
IElementType EXPRESSION_TEXT = new ICodeFragmentElementType("EXPRESSION_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ExpressionParser.parse(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
final PsiManager manager = ((FileElement)chameleon).getManager();
|
||||
final JavaParsingContext context = new JavaParsingContext(SharedImplUtil.findCharTableByTree(chameleon), LanguageLevel.HIGHEST);
|
||||
@@ -183,17 +226,37 @@ public interface JavaElementType {
|
||||
}
|
||||
};
|
||||
|
||||
IElementType REFERENCE_TEXT = new ICodeFragmentElementType("REFERENCE_TEXT", StdLanguages.JAVA){
|
||||
public ASTNode parseContents(ASTNode chameleon) {
|
||||
IElementType REFERENCE_TEXT = new ICodeFragmentElementType("REFERENCE_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseJavaCodeReference(builder, false, true, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
return Parsing.parseJavaCodeReferenceText(((FileElement)chameleon).getManager(), chars, 0, chars.length(), SharedImplUtil.findCharTableByTree(chameleon), true);
|
||||
return Parsing.parseJavaCodeReferenceText(((FileElement)chameleon).getManager(), chars, 0, chars.length(),
|
||||
SharedImplUtil.findCharTableByTree(chameleon), true);
|
||||
}
|
||||
};
|
||||
|
||||
IElementType TYPE_TEXT = new ICodeFragmentElementType("TYPE_TEXT", StdLanguages.JAVA){
|
||||
public ASTNode parseContents(ASTNode chameleon) {
|
||||
IElementType TYPE_TEXT = new ICodeFragmentElementType("TYPE_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseType(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
return Parsing.parseTypeText(((FileElement)chameleon).getManager(), null, chars, 0, chars.length(), 0, SharedImplUtil.findCharTableByTree(chameleon));
|
||||
return Parsing.parseTypeText(((FileElement)chameleon).getManager(), null, chars, 0, chars.length(), 0,
|
||||
SharedImplUtil.findCharTableByTree(chameleon));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ class JavaChangeInfoImpl implements JavaChangeInfo {
|
||||
if (!newName.equals(that.newName)) return false;
|
||||
if (newNameIdentifier != null ? !newNameIdentifier.equals(that.newNameIdentifier) : that.newNameIdentifier != null) return false;
|
||||
if (!Arrays.equals(newParms, that.newParms)) return false;
|
||||
if (newReturnType != null ? !Comparing.strEqual(newReturnType.getTypeText(), that.newReturnType.getTypeText()) : that.newReturnType != null) return false;
|
||||
if (newReturnType != null ? that.newReturnType == null || !Comparing.strEqual(newReturnType.getTypeText(), that.newReturnType.getTypeText()) : that.newReturnType != null) return false;
|
||||
if (newVisibility != null ? !newVisibility.equals(that.newVisibility) : that.newVisibility != null) return false;
|
||||
if (!oldName.equals(that.oldName)) return false;
|
||||
if (!Arrays.equals(oldParameterNames, that.oldParameterNames)) return false;
|
||||
|
||||
+10
-1
@@ -124,6 +124,7 @@ class IntroduceConstantDialog extends DialogWrapper {
|
||||
myVPanel.setVisibility(JavaRefactoringSettings.getInstance().INTRODUCE_CONSTANT_VISIBILITY);
|
||||
myIntroduceEnumConstantCb.setEnabled(EnumConstantsUtil.isSuitableForEnumConstant(getSelectedType(), myTargetClass));
|
||||
updateVisibilityPanel();
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
public String getEnteredName() {
|
||||
@@ -172,7 +173,11 @@ class IntroduceConstantDialog extends DialogWrapper {
|
||||
|
||||
myNameField = new NameSuggestionsField(myProject);
|
||||
myNameSuggestionPanel.setLayout(new BorderLayout());
|
||||
|
||||
myNameField.addDataChangedListener(new NameSuggestionsField.DataChanged() {
|
||||
public void dataChanged() {
|
||||
updateButtons();
|
||||
}
|
||||
});
|
||||
myNameSuggestionPanel.add(myNameField.getComponent(), BorderLayout.CENTER);
|
||||
myNameSuggestionLabel.setLabelFor(myNameField.getFocusableComponent());
|
||||
|
||||
@@ -280,6 +285,10 @@ class IntroduceConstantDialog extends DialogWrapper {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
private void updateButtons() {
|
||||
setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getEnteredName()));
|
||||
}
|
||||
|
||||
private void targetClassChanged() {
|
||||
final String targetClassName = getTargetClassName();
|
||||
myTargetClass = JavaPsiFacade.getInstance(myProject).findClass(targetClassName, GlobalSearchScope.projectScope(myProject));
|
||||
|
||||
+12
-2
@@ -30,7 +30,6 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import static com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler.InitializationPlace.*;
|
||||
import com.intellij.refactoring.ui.*;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.RefactoringMessageUtil;
|
||||
@@ -43,6 +42,8 @@ import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
|
||||
import static com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler.InitializationPlace.*;
|
||||
|
||||
class IntroduceFieldDialog extends DialogWrapper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.introduceField.IntroduceFieldDialog");
|
||||
|
||||
@@ -103,7 +104,7 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
init();
|
||||
|
||||
initializeControls(initializerExpression);
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
private void initializeControls(PsiExpression initializerExpression) {
|
||||
@@ -270,6 +271,11 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
gbConstraints.gridy = 1;
|
||||
myNameField = new NameSuggestionsField(myProject);
|
||||
panel.add(myNameField.getComponent(), gbConstraints);
|
||||
myNameField.addDataChangedListener(new NameSuggestionsField.DataChanged() {
|
||||
public void dataChanged() {
|
||||
updateButtons();
|
||||
}
|
||||
});
|
||||
namePrompt.setLabelFor(myNameField.getFocusableComponent());
|
||||
|
||||
myNameSuggestionsManager = new NameSuggestionsManager(myTypeSelector, myNameField, createGenerator());
|
||||
@@ -278,6 +284,10 @@ class IntroduceFieldDialog extends DialogWrapper {
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void updateButtons() {
|
||||
setOKActionEnabled(JavaPsiFacade.getInstance(myProject).getNameHelper().isIdentifier(getEnteredName()));
|
||||
}
|
||||
|
||||
private String getTypeLabel() {
|
||||
return myWillBeDeclaredStatic ?
|
||||
RefactoringBundle.message("introduce.field.static.field.of.type") :
|
||||
|
||||
+4
-3
@@ -17,6 +17,7 @@ package com.intellij.refactoring.rename;
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.pom.PomTarget;
|
||||
import com.intellij.pom.PomTargetPsiElement;
|
||||
import com.intellij.pom.references.PomService;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiTarget;
|
||||
@@ -30,14 +31,14 @@ public class RenameAliasingPomTargetProcessor extends RenamePsiElementProcessor
|
||||
|
||||
@Override
|
||||
public boolean canProcessElement(@Nullable PsiElement element) {
|
||||
return element instanceof PomTarget;
|
||||
return element instanceof PomTargetPsiElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareRenaming(PsiElement element, String newName, Map<PsiElement, String> allRenames) {
|
||||
if (element instanceof PsiTarget) {
|
||||
if (element instanceof PomTargetPsiElement) {
|
||||
for (AliasingPsiTargetMapper mapper : Extensions.getExtensions(AliasingPsiTargetMapper.EP_NAME)) {
|
||||
for (AliasingPsiTarget psiTarget : mapper.getTargets((PsiTarget)element)) {
|
||||
for (AliasingPsiTarget psiTarget : mapper.getTargets(((PomTargetPsiElement)element).getTarget())) {
|
||||
allRenames.put(PomService.convertToPsi(psiTarget), psiTarget.getNameAlias(newName));
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Change signature of 'f(int...)' to 'f(String, int...)'" "true"
|
||||
public class S {
|
||||
void f(String s, int... args) {
|
||||
f("",1,1);
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Change signature of 'f(int...)' to 'f(String, int...)'" "true"
|
||||
public class S {
|
||||
void f(String s, int... args) {
|
||||
f("",null);
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Change signature of 'f(int...)' to 'f(String, int...)'" "true"
|
||||
public class S {
|
||||
void f(int... args) {
|
||||
f("",1,1)<caret>;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Change signature of 'f(int...)' to 'f(String, int...)'" "true"
|
||||
public class S {
|
||||
void f(int... args) {
|
||||
f("",null)<caret>;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// "Change signature of 'f(int...)' to 'f(int..., String)'" "false"
|
||||
public class S {
|
||||
void f(int... args) {
|
||||
f(1,1, "")<caret>;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class A {
|
||||
{
|
||||
List<Integer> l = new ArrayList<Integer>();
|
||||
for (Integer i : l) {
|
||||
final String tostr = i.toString();
|
||||
System.out.println(tostr);
|
||||
}
|
||||
for (Integer i : l) {
|
||||
System.out.println(i.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class A {
|
||||
{
|
||||
List<Integer> l = new ArrayList<Integer>();
|
||||
for (Integer i : l) {
|
||||
System.out.println(<selection>i.toString()</selection>);
|
||||
}
|
||||
for (Integer i : l) {
|
||||
System.out.println(i.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.intellij.lang.java.parser;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
@@ -120,7 +121,9 @@ public abstract class JavaParsingTestCase extends ParsingTestCase {
|
||||
@Override
|
||||
protected void doTest(final boolean checkResult) {
|
||||
doTestDefaultParser(checkResult);
|
||||
doTestNewParser();
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
doTestNewParser();
|
||||
}
|
||||
}
|
||||
|
||||
protected void doTestDefaultParser(final boolean checkResult) {
|
||||
|
||||
@@ -218,6 +218,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase {
|
||||
doTest(new MockIntroduceVariableHandler("foo1", true, true, false, "Foo"));
|
||||
}
|
||||
|
||||
public void testDifferentForeachParameters () throws Exception {
|
||||
doTest(new MockIntroduceVariableHandler("tostr", true, true, false, "java.lang.String"));
|
||||
}
|
||||
|
||||
public void testSiblingInnerClassType() throws Exception {
|
||||
doTest(new MockIntroduceVariableHandler("vari", true, false, false, "A.B"){
|
||||
@Override
|
||||
|
||||
@@ -57,7 +57,7 @@ public interface PsiJavaFile extends PsiImportHolder, PsiClassOwner {
|
||||
@NotNull PsiElement[] getOnDemandImports(boolean includeImplicit, @Deprecated boolean checkIncludes);
|
||||
|
||||
/**
|
||||
* Returns the list of classs which have been imported as
|
||||
* Returns the list of classes which have been imported as
|
||||
* single-class imports.
|
||||
*
|
||||
* @param checkIncludes deprecated, no longer used.
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.lookup;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -61,6 +62,14 @@ public abstract class LookupElement extends UserDataHolderBase {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
final Object object = getObject();
|
||||
if (object instanceof PsiElement) {
|
||||
return ((PsiElement)object).isValid();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void handleInsert(InsertionContext context) {
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,19 @@ package com.intellij.openapi.project;
|
||||
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ProjectLocatorImpl extends ProjectLocator {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Project guessProjectForFile(final VirtualFile file) {
|
||||
ProjectManager projectManager = ProjectManager.getInstance();
|
||||
if (projectManager == null) return null;
|
||||
if (projectManager == null || file == null) return null;
|
||||
final Project[] projects = projectManager.getOpenProjects();
|
||||
if (projects.length == 0) return null;
|
||||
if (projects.length == 1 && !projects[0].isDisposed()) return projects[0];
|
||||
@@ -40,4 +46,23 @@ public class ProjectLocatorImpl extends ProjectLocator {
|
||||
|
||||
return !projects[0].isDisposed() ? projects[0] : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<Project> getProjectsForFile(VirtualFile file) {
|
||||
final Collection<Project> result = new HashSet<Project>();
|
||||
|
||||
final ProjectManager projectManager = ProjectManager.getInstance();
|
||||
if (projectManager == null || file == null) { return result; }
|
||||
final Project[] openProjects = projectManager.getOpenProjects();
|
||||
if (openProjects.length == 0) { return result; }
|
||||
|
||||
for (Project project : openProjects) {
|
||||
if (project.isInitialized() && !project.isDisposed() && ProjectRootManager.getInstance(project).getFileIndex().isInContent(file)) {
|
||||
result.add(project);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,5 @@ public interface AliasingPsiTargetMapper {
|
||||
ExtensionPointName<AliasingPsiTargetMapper> EP_NAME = ExtensionPointName.create("com.intellij.aliasingPsiTargetMapper");
|
||||
|
||||
@NotNull
|
||||
Set<AliasingPsiTarget> getTargets(@NotNull PomTarget psiTarget);
|
||||
Set<AliasingPsiTarget> getTargets(@NotNull PomTarget target);
|
||||
}
|
||||
|
||||
-9
@@ -304,15 +304,6 @@ public abstract class OptionTableWithPreviewPanel extends MultilanguageCodeStyle
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void addOption(Class<? extends CustomCodeStyleSettings> clazz, @NotNull String fieldName, @NotNull String title, @Nullable String groupName) {
|
||||
myOptions.add(new BooleanOption(clazz, fieldName, title, groupName));
|
||||
}
|
||||
|
||||
protected void addOption(Class<? extends CustomCodeStyleSettings> clazz, @NotNull String fieldName, @NotNull String title, @Nullable String groupName,
|
||||
@NotNull String[] options, @NotNull int[] values) {
|
||||
myOptions.add(new SelectionOption(clazz, fieldName, title, groupName, options, values));
|
||||
}
|
||||
|
||||
protected void addOption(@NotNull String fieldName, @NotNull String title) {
|
||||
addOption(fieldName, title, null);
|
||||
}
|
||||
|
||||
@@ -96,12 +96,8 @@ public class AutoPopupController implements Disposable {
|
||||
new CodeCompletionHandlerBase(CompletionType.BASIC, false, false).invoke(myProject, editor, file);
|
||||
}
|
||||
};
|
||||
// invoke later prevents cancelling request by keyPressed from the same action
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
myAlarm.addRequest(request, settings.AUTO_LOOKUP_DELAY);
|
||||
}
|
||||
});
|
||||
|
||||
myAlarm.addRequest(request, settings.AUTO_LOOKUP_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,12 +108,7 @@ public class AutoPopupController implements Disposable {
|
||||
currentCompletion.closeAndFinish();
|
||||
}
|
||||
|
||||
// invoke later prevents cancelling request by keyPressed from the same action
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
myAlarm.addRequest(request, delay);
|
||||
}
|
||||
});
|
||||
myAlarm.addRequest(request, delay);
|
||||
}
|
||||
|
||||
public void autoPopupParameterInfo(final Editor editor, final PsiElement highlightedMethod){
|
||||
@@ -145,12 +136,8 @@ public class AutoPopupController implements Disposable {
|
||||
}
|
||||
}
|
||||
};
|
||||
// invoke later prevents cancelling request by keyPressed from the same action
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
myAlarm.addRequest(request, settings.PARAMETER_INFO_DELAY);
|
||||
}
|
||||
});
|
||||
|
||||
myAlarm.addRequest(request, settings.PARAMETER_INFO_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -539,7 +539,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
}
|
||||
|
||||
public boolean isRepeatedInvocation(CompletionType completionType, Editor editor) {
|
||||
return completionType == myParameters.getCompletionType() && editor == myEditor;
|
||||
return completionType == myParameters.getCompletionType() && editor == myEditor && !isAutopopupCompletion();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -116,11 +116,8 @@ public class LookupCellRenderer implements ListCellRenderer {
|
||||
boolean hasFocus) {
|
||||
|
||||
|
||||
if (isSelected && !myLookup.isFocused() && myLookup.isCompletion()) {
|
||||
//myPanel.setBorder(new DottedBorder(Color.gray));
|
||||
if (!myLookup.isFocused()) {
|
||||
isSelected = false;
|
||||
} else {
|
||||
//myPanel.setBorder(null);
|
||||
}
|
||||
|
||||
final LookupElement item = (LookupElement)value;
|
||||
|
||||
@@ -112,7 +112,7 @@ public class LookupImpl extends LightweightHint implements Lookup, Disposable {
|
||||
|
||||
public LookupImpl(Project project, Editor editor, @NotNull LookupArranger arranger){
|
||||
super(new JPanel(new BorderLayout()));
|
||||
setForceShowAsPopup(!SystemInfo.isLinux);
|
||||
setForceShowAsPopup(true);
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
myArranger = arranger;
|
||||
|
||||
+1
-1
@@ -42,6 +42,6 @@ public class ChooseItemReplaceAction extends EditorAction {
|
||||
|
||||
public void update(Editor editor, Presentation presentation, DataContext dataContext){
|
||||
LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor);
|
||||
presentation.setEnabled(lookup != null && lookup.isFocused());
|
||||
presentation.setEnabled(lookup != null && (lookup.isFocused() || lookup.isCompletion() && !lookup.getItems().isEmpty()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.actions.CreateFileFromTemplateDialog">
|
||||
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="84"/>
|
||||
@@ -17,21 +17,14 @@
|
||||
<text value="&Name:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f8fb3" class="javax.swing.JLabel">
|
||||
<component id="f8fb3" class="javax.swing.JLabel" binding="myKindLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="48008"/>
|
||||
<text value="&Kind:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="48008" class="javax.swing.JComboBox" binding="myKindCombo">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="b76e" class="javax.swing.JTextField" binding="myNameField">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
@@ -50,6 +43,17 @@
|
||||
<toolTipText value="Pressing Up or Down arrows while in editor changes the kind"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="115cf">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="81412" class="com.intellij.ide.actions.TemplateKindCombo" binding="myKindCombo">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
@@ -41,60 +41,19 @@ import java.awt.event.KeyEvent;
|
||||
* @author peter
|
||||
*/
|
||||
public class CreateFileFromTemplateDialog extends DialogWrapper {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.CreateFileFromTemplateDialog");
|
||||
private JTextField myNameField;
|
||||
private JComboBox myKindCombo;
|
||||
private TemplateKindCombo myKindCombo;
|
||||
private JPanel myPanel;
|
||||
private JLabel myUpDownHint;
|
||||
private JLabel myKindLabel;
|
||||
|
||||
private ElementCreator myCreator;
|
||||
|
||||
private CreateFileFromTemplateDialog(@NotNull Project project) {
|
||||
super(project, true);
|
||||
|
||||
myKindCombo.setRenderer(new DefaultListCellRenderer() {
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
@SuppressWarnings({"unchecked"}) Trinity<String, Icon, String> trinity = (Trinity<String, Icon, String>) value;
|
||||
setText(trinity == null ? "" : trinity.first);
|
||||
setIcon(trinity == null ? null : trinity.second);
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
//myNameLabel.setText(prompt);
|
||||
|
||||
new ComboboxSpeedSearch(myKindCombo) {
|
||||
@Override
|
||||
protected String getElementText(Object element) {
|
||||
return ((Trinity<String, Icon, String>)element).first;
|
||||
}
|
||||
};
|
||||
|
||||
final AnAction arrow = new AnAction() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (e.getInputEvent() instanceof KeyEvent) {
|
||||
final int code = ((KeyEvent)e.getInputEvent()).getKeyCode();
|
||||
final int delta = code == KeyEvent.VK_DOWN ? 1 : code == KeyEvent.VK_UP ? -1 : 0;
|
||||
|
||||
final int size = myKindCombo.getModel().getSize();
|
||||
int next = myKindCombo.getSelectedIndex() + delta;
|
||||
if (next < 0 || next >= size) {
|
||||
if (!UISettings.getInstance().CYCLE_SCROLLING) {
|
||||
return;
|
||||
}
|
||||
next = (next + size) % size;
|
||||
}
|
||||
myKindCombo.setSelectedIndex(next);
|
||||
}
|
||||
}
|
||||
};
|
||||
final KeyboardShortcut up = new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), null);
|
||||
final KeyboardShortcut down = new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), null);
|
||||
arrow.registerCustomShortcutSet(new CustomShortcutSet(up, down), myNameField);
|
||||
|
||||
myKindLabel.setLabelFor(myKindCombo);
|
||||
myKindCombo.registerUpDownHint(myNameField);
|
||||
myUpDownHint.setIcon(Icons.UP_DOWN_ARROWS);
|
||||
init();
|
||||
}
|
||||
@@ -103,16 +62,6 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
|
||||
return myNameField.getText();
|
||||
}
|
||||
|
||||
private String getTemplateName() {
|
||||
//noinspection unchecked
|
||||
final Trinity<String, Icon, String> trinity = (Trinity<String, Icon, String>)myKindCombo.getSelectedItem();
|
||||
if (trinity == null) {
|
||||
LOG.error("Model: " + myKindCombo.getModel());
|
||||
}
|
||||
|
||||
return trinity.third;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myPanel;
|
||||
@@ -143,36 +92,23 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
public Builder addKind(@NotNull String name, @Nullable Icon icon, @NotNull String templateName) {
|
||||
dialog.myKindCombo.addItem(new Trinity<String, Icon, String>(name, icon, templateName));
|
||||
dialog.myKindCombo.addItem(name, icon, templateName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T extends PsiElement> T show(@NotNull String errorTitle, @Nullable String selectedTemplateName,
|
||||
@NotNull final FileCreator<T> creator) {
|
||||
final Ref<T> created = Ref.create(null);
|
||||
if (selectedTemplateName != null) {
|
||||
Object item = null;
|
||||
ComboBoxModel model = dialog.myKindCombo.getModel();
|
||||
for (int i = 0, n = model.getSize(); i < n; i++) {
|
||||
Trinity<String, Icon, String> trinity = (Trinity<String, Icon, String>)model.getElementAt(i);
|
||||
if (selectedTemplateName.equals(trinity.third)) {
|
||||
item = trinity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (item != null) {
|
||||
dialog.myKindCombo.setSelectedItem(item);
|
||||
}
|
||||
}
|
||||
dialog.myKindCombo.setSelectedName(selectedTemplateName);
|
||||
dialog.myCreator = new ElementCreator(project, errorTitle) {
|
||||
@Override
|
||||
protected void checkBeforeCreate(String newName) throws IncorrectOperationException {
|
||||
creator.checkBeforeCreate(newName, dialog.getTemplateName());
|
||||
creator.checkBeforeCreate(newName, dialog.myKindCombo.getSelectedName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PsiElement[] create(String newName) throws Exception {
|
||||
final T element = creator.createFile(dialog.getEnteredName(), dialog.getTemplateName());
|
||||
final T element = creator.createFile(dialog.getEnteredName(), dialog.myKindCombo.getSelectedName());
|
||||
created.set(element);
|
||||
if (element != null) {
|
||||
return new PsiElement[]{element};
|
||||
@@ -182,7 +118,7 @@ public class CreateFileFromTemplateDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
protected String getActionName(String newName) {
|
||||
return creator.getActionName(newName, dialog.getTemplateName());
|
||||
return creator.getActionName(newName, dialog.myKindCombo.getSelectedName());
|
||||
}
|
||||
};
|
||||
dialog.show();
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ide.ui.UISettings;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CustomShortcutSet;
|
||||
import com.intellij.openapi.actionSystem.KeyboardShortcut;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.ui.ComboboxSpeedSearch;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
public class TemplateKindCombo extends JComboBox {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.TemplateKindCombo");
|
||||
|
||||
public TemplateKindCombo() {
|
||||
super();
|
||||
|
||||
setRenderer(new ListCellRendererWrapper(getRenderer()) {
|
||||
@Override
|
||||
public String getDisplayedName(Object value) {
|
||||
if (value instanceof Trinity) {
|
||||
return (String)((Trinity)value).first;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon(Object value) {
|
||||
if (value instanceof Trinity) {
|
||||
return (Icon)((Trinity)value).second;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
new ComboboxSpeedSearch(this) {
|
||||
@Override
|
||||
protected String getElementText(Object element) {
|
||||
if (element instanceof Trinity) {
|
||||
return (String)((Trinity)element).first;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void addItem(String presentableName, Icon icon, String templateName) {
|
||||
addItem(new Trinity<String, Icon, String>(presentableName, icon, templateName));
|
||||
}
|
||||
|
||||
public String getSelectedName() {
|
||||
//noinspection unchecked
|
||||
final Trinity<String, Icon, String> trinity = (Trinity<String, Icon, String>)getSelectedItem();
|
||||
if (trinity == null) {
|
||||
LOG.error("Model: " + getModel());
|
||||
}
|
||||
return trinity.third;
|
||||
}
|
||||
|
||||
public void setSelectedName(@Nullable String name) {
|
||||
if (name == null) return;
|
||||
ComboBoxModel model = getModel();
|
||||
for (int i = 0, n = model.getSize(); i < n; i++) {
|
||||
Trinity<String, Icon, String> trinity = (Trinity<String, Icon, String>)model.getElementAt(i);
|
||||
if (name.equals(trinity.third)) {
|
||||
setSelectedItem(trinity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerUpDownHint(JComponent component) {
|
||||
final AnAction arrow = new AnAction() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (e.getInputEvent() instanceof KeyEvent) {
|
||||
final int code = ((KeyEvent)e.getInputEvent()).getKeyCode();
|
||||
scrollBy(code == KeyEvent.VK_DOWN ? 1 : code == KeyEvent.VK_UP ? -1 : 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
final KeyboardShortcut up = new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), null);
|
||||
final KeyboardShortcut down = new KeyboardShortcut(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), null);
|
||||
arrow.registerCustomShortcutSet(new CustomShortcutSet(up, down), component);
|
||||
}
|
||||
|
||||
private void scrollBy(int delta) {
|
||||
final int size = getModel().getSize();
|
||||
int next = getSelectedIndex() + delta;
|
||||
if (next < 0 || next >= size) {
|
||||
if (!UISettings.getInstance().CYCLE_SCROLLING) {
|
||||
return;
|
||||
}
|
||||
next = (next + size) % size;
|
||||
}
|
||||
setSelectedIndex(next);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,8 +34,10 @@ public class NavigatableRule implements GetDataRule {
|
||||
return openFileDescriptor;
|
||||
}
|
||||
}
|
||||
|
||||
final PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataProvider);
|
||||
if (element instanceof Navigatable) {
|
||||
return element;
|
||||
}
|
||||
if (element != null) {
|
||||
return EditSourceUtil.getDescriptor(element);
|
||||
}
|
||||
|
||||
+19
-9
@@ -16,28 +16,31 @@
|
||||
package com.intellij.ide.scriptingContext;
|
||||
|
||||
import com.intellij.ide.scriptingContext.ui.ScriptingLibrariesPanel;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Rustam Vishnyakov <dyadix@gmail.com>
|
||||
* @author Rustam Vishnyakov
|
||||
*/
|
||||
public class LangScriptingContextConfigurable implements Configurable {
|
||||
private ScriptingLibrariesPanel myPanel;
|
||||
private LangScriptingContextProvider myProvider;
|
||||
private ModifiableRootModel myRootModel;
|
||||
|
||||
public LangScriptingContextConfigurable(Project project, LangScriptingContextProvider provider) {
|
||||
myRootModel = ScriptingLibraryManager.getRootModel(project);
|
||||
if (myRootModel != null) {
|
||||
myPanel = new ScriptingLibrariesPanel(myRootModel.getModuleLibraryTable());
|
||||
}
|
||||
public LangScriptingContextConfigurable(ModifiableRootModel rootModel, LangScriptingContextProvider provider) {
|
||||
LibraryTable libTable = rootModel != null ?
|
||||
rootModel.getModuleLibraryTable() : null;
|
||||
myPanel = new ScriptingLibrariesPanel(libTable);
|
||||
myProvider = provider;
|
||||
myRootModel = rootModel;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@@ -63,12 +66,19 @@ public class LangScriptingContextConfigurable implements Configurable {
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||
return myPanel.isModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
if (myRootModel != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myRootModel.commit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -78,6 +88,6 @@ public class LangScriptingContextConfigurable implements Configurable {
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
myRootModel.dispose();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+15
-3
@@ -16,9 +16,11 @@
|
||||
package com.intellij.ide.scriptingContext;
|
||||
|
||||
import com.intellij.ide.scriptingContext.ui.MainScriptingContextsPanel;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -32,11 +34,13 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable
|
||||
private MainScriptingContextsPanel myPanel;
|
||||
private String myLangNames;
|
||||
private Project myProject;
|
||||
private ModifiableRootModel myRootModel;
|
||||
|
||||
public ScriptingContextsConfigurable(Project project) {
|
||||
myPanel = new MainScriptingContextsPanel();
|
||||
myLangNames = getLangNames();
|
||||
myProject = project;
|
||||
myRootModel = ScriptingLibraryManager.getRootModel(project);
|
||||
}
|
||||
|
||||
@Nls
|
||||
@@ -67,7 +71,9 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable
|
||||
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
if (myRootModel != null) {
|
||||
myRootModel.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,14 +83,14 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
disposeModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Configurable[] getConfigurables() {
|
||||
ArrayList<LangScriptingContextConfigurable> configurables = new ArrayList<LangScriptingContextConfigurable>();
|
||||
for (LangScriptingContextProvider provider : LangScriptingContextProvider.getProviders()) {
|
||||
configurables.add(new LangScriptingContextConfigurable(myProject, provider));
|
||||
configurables.add(new LangScriptingContextConfigurable(myRootModel, provider));
|
||||
}
|
||||
return configurables.toArray(new LangScriptingContextConfigurable[configurables.size()]);
|
||||
}
|
||||
@@ -97,4 +103,10 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable
|
||||
String result = buf.toString();
|
||||
return result.substring(0, result.length() - 1);
|
||||
}
|
||||
|
||||
public void disposeModel() {
|
||||
if (myRootModel != null && !myRootModel.isDisposed()) {
|
||||
myRootModel.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,8 @@ public class EditLibraryDialog extends DialogWrapper {
|
||||
protected JComponent createCenterPanel() {
|
||||
return contentPane;
|
||||
}
|
||||
|
||||
public String getLibName() {
|
||||
return myLibName.getText();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="76cd4" class="javax.swing.JButton" binding="myAddLibrarytButton">
|
||||
<component id="76cd4" class="javax.swing.JButton" binding="myAddLibraryButton">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
@@ -45,7 +45,7 @@
|
||||
<text value="Remove"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="7d17d" class="javax.swing.JButton" binding="myEditLibrarytButton">
|
||||
<component id="7d17d" class="javax.swing.JButton" binding="myEditLibraryButton">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
|
||||
+24
-8
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ide.scriptingContext.ui;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.libraries.LibraryTable;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -30,20 +27,29 @@ import java.awt.event.ActionListener;
|
||||
*/
|
||||
public class ScriptingLibrariesPanel {
|
||||
private JPanel myTopPanel;
|
||||
private JButton myAddLibrarytButton;
|
||||
private JButton myAddLibraryButton;
|
||||
private JButton myRemoveLibraryButton;
|
||||
private JButton myEditLibrarytButton;
|
||||
private JButton myEditLibraryButton;
|
||||
private JPanel myScriptingLibrariesPanel;
|
||||
private JBTable myLibraryTable;
|
||||
private ScriptingLibraryTableModel myLibTableModel;
|
||||
private boolean myModified;
|
||||
|
||||
public ScriptingLibrariesPanel(LibraryTable libTable) {
|
||||
myLibraryTable.setModel(new ScriptingLibraryTableModel(libTable));
|
||||
myAddLibrarytButton.addActionListener(new ActionListener(){
|
||||
myLibTableModel = new ScriptingLibraryTableModel(libTable);
|
||||
myLibraryTable.setModel(myLibTableModel);
|
||||
myAddLibraryButton.addActionListener(new ActionListener(){
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addLibrary();
|
||||
}
|
||||
});
|
||||
if (libTable == null) {
|
||||
myAddLibraryButton.setEnabled(false);
|
||||
}
|
||||
myRemoveLibraryButton.setEnabled(false);
|
||||
myEditLibraryButton.setEnabled(false);
|
||||
myModified = false;
|
||||
}
|
||||
|
||||
public JPanel getPanel() {
|
||||
@@ -54,8 +60,18 @@ public class ScriptingLibrariesPanel {
|
||||
EditLibraryDialog editLibDialog = new EditLibraryDialog();
|
||||
editLibDialog.show();
|
||||
if (editLibDialog.isOK()) {
|
||||
//TODO: Implement
|
||||
createLibrary(editLibDialog.getLibName());
|
||||
myModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void createLibrary(String name) {
|
||||
myLibTableModel.getLibraryTable().createLibrary(name);
|
||||
myLibraryTable.repaint();
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return myModified;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-1
@@ -38,7 +38,10 @@ public class ScriptingLibraryTableModel extends AbstractTableModel {
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return myLibTable.getLibraries().length;
|
||||
if (myLibTable != null) {
|
||||
return myLibTable.getLibraries().length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,4 +65,8 @@ public class ScriptingLibraryTableModel extends AbstractTableModel {
|
||||
return "?";
|
||||
}
|
||||
|
||||
public LibraryTable getLibraryTable() {
|
||||
return myLibTable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -924,6 +924,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
|
||||
}
|
||||
else if (item instanceof DoneMarker) {
|
||||
curNode = nodes.pop();
|
||||
item.next = i < myProduction.size() - 1 ? myProduction.get(i + 1) : null;
|
||||
}
|
||||
else if (item instanceof ErrorItem) {
|
||||
int curToken = item.myLexemeIndex;
|
||||
@@ -986,10 +987,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
|
||||
CompositeElement curNode = rootNode;
|
||||
|
||||
int lexIndex = rootMarker.myLexemeIndex;
|
||||
int lastErrorIndex = -1;
|
||||
for (int i = myProduction.indexOf(rootMarker) + 1; i <= myProduction.indexOf(rootMarker.myDoneMarker); i++) {
|
||||
final ProductionMarker item = myProduction.get(i);
|
||||
|
||||
ProductionMarker item = rootMarker.firstChild != null ? rootMarker.firstChild : rootMarker.myDoneMarker;
|
||||
while (item != null) {
|
||||
lexIndex = insertLeaves(lexIndex, item.myLexemeIndex, curNode);
|
||||
|
||||
if (item instanceof StartMarker) {
|
||||
@@ -1002,25 +1001,24 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
|
||||
curNode.rawAddChildren(childNode);
|
||||
nodes.push(curNode);
|
||||
curNode = childNode;
|
||||
|
||||
item = marker.firstChild != null ? marker.firstChild : marker.myDoneMarker;
|
||||
}
|
||||
else {
|
||||
lexIndex = collapseLeaves(curNode, marker);
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
i = myProduction.indexOf(marker.myDoneMarker);
|
||||
item = marker.myDoneMarker.next;
|
||||
}
|
||||
}
|
||||
else if (item instanceof ErrorItem) {
|
||||
final PsiErrorElementImpl errorElement = new PsiErrorElementImpl();
|
||||
errorElement.setErrorDescription(((ErrorItem)item).myMessage);
|
||||
curNode.rawAddChildren(errorElement);
|
||||
item = item.next != null ? item.next : curMarker.myDoneMarker;
|
||||
}
|
||||
else if (item instanceof DoneMarker) {
|
||||
curMarker = markers.pop();
|
||||
curNode = nodes.pop();
|
||||
}
|
||||
else if (item instanceof ErrorItem) {
|
||||
int curToken = item.myLexemeIndex;
|
||||
if (curToken == lastErrorIndex) continue;
|
||||
lastErrorIndex = curToken;
|
||||
|
||||
final PsiErrorElementImpl errorElement = new PsiErrorElementImpl();
|
||||
errorElement.setErrorDescription(((ErrorItem)item).myMessage);
|
||||
curNode.rawAddChildren(errorElement);
|
||||
item = item.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.refactoring.changeSignature;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -29,6 +30,7 @@ import com.intellij.openapi.editor.event.EditorFactoryListener;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
@@ -92,13 +94,17 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
|
||||
public void projectOpened() {
|
||||
myPsiManager.addPsiTreeChangeListener(this);
|
||||
EditorFactory.getInstance().addEditorFactoryListener(this);
|
||||
Disposer.register(myPsiManager.getProject(), new Disposable() {
|
||||
public void dispose() {
|
||||
myPsiManager.removePsiTreeChangeListener(ChangeSignatureGestureDetector.this);
|
||||
EditorFactory.getInstance().removeEditorFactoryListener(ChangeSignatureGestureDetector.this);
|
||||
myListenerMap.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectClosed() {
|
||||
myListenerMap.clear();
|
||||
myPsiManager.removePsiTreeChangeListener(this);
|
||||
EditorFactory.getInstance().removeEditorFactoryListener(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -213,7 +213,7 @@ public class BrowserUtil {
|
||||
@NotNull
|
||||
public static String escapeUrl(@NotNull @NonNls String url) {
|
||||
if (SystemInfo.isWindows) {
|
||||
return url.indexOf(' ') > 0? "\"" + url + "\"" : url;
|
||||
return (url.indexOf(' ') > 0 || url.indexOf('&') > -1) ? "\"" + url + "\"" : url;
|
||||
}
|
||||
else {
|
||||
return url.replaceAll(" ", "%20");
|
||||
@@ -383,15 +383,11 @@ public class BrowserUtil {
|
||||
}
|
||||
|
||||
public static boolean canStartDefaultBrowser() {
|
||||
if (SystemInfo.isMac) {
|
||||
if (SystemInfo.isMac || SystemInfo.isWindows) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SystemInfo.isWindows) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SystemInfo.isLinux && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
if (SystemInfo.isLinux && Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,13 +21,33 @@ package com.intellij.openapi.project;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class ProjectLocator {
|
||||
|
||||
public static ProjectLocator getInstance() {
|
||||
return ServiceManager.getService(ProjectLocator.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an open project which contains the given file.
|
||||
* This is a guess-method, so if several projects contain the file, only one will be returned.
|
||||
* Also a project may be returned though it doesn't contain the file for sure (see implementations).
|
||||
* @param file file to be located in projects.
|
||||
* @return project which probably contains the file, or null if couldn't guess (for example, there are no open projects).
|
||||
*/
|
||||
@Nullable
|
||||
public abstract Project guessProjectForFile(VirtualFile file);
|
||||
|
||||
/**
|
||||
* Gets all open projects containing the given file.
|
||||
* If none does, an empty list is returned.
|
||||
* @param file file to be located in projects.
|
||||
* @return list of open projects containing this file.
|
||||
*/
|
||||
@NotNull
|
||||
public abstract Collection<Project> getProjectsForFile(VirtualFile file);
|
||||
}
|
||||
@@ -219,6 +219,17 @@ public class Messages {
|
||||
return showDialog(message, title, new String[]{OK_BUTTON, CANCEL_BUTTON}, 0, icon);
|
||||
}
|
||||
|
||||
public static int shpwTwoStepConfirmationDialog(String message, String title, String checkboxText, Icon icon) {
|
||||
if (isApplicationInUnitTestOrHeadless()) {
|
||||
return ourTestImplementation.show(message);
|
||||
}
|
||||
else {
|
||||
TwoStepConfirmationDialog dialog = new TwoStepConfirmationDialog(message, title, checkboxText, icon);
|
||||
dialog.show();
|
||||
return dialog.getExitCode();
|
||||
}
|
||||
}
|
||||
|
||||
public static void showErrorDialog(Project project, @Nls String message, @Nls String title) {
|
||||
showDialog(project, message, title, new String[]{OK_BUTTON}, 0, getErrorIcon());
|
||||
}
|
||||
@@ -548,7 +559,11 @@ public class Messages {
|
||||
this(message, title, options, defaultOptionIndex, -1, icon, doNotAskOption);
|
||||
}
|
||||
|
||||
private void _init(String title, String message, String[] options, int defaultOptionIndex, int focusedOptionIndex, Icon icon, DoNotAskOption doNotAskOption) {
|
||||
protected MessageDialog() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
protected void _init(String title, String message, String[] options, int defaultOptionIndex, int focusedOptionIndex, Icon icon, DoNotAskOption doNotAskOption) {
|
||||
setTitle(title);
|
||||
myMessage = message;
|
||||
myOptions = options;
|
||||
@@ -673,6 +688,62 @@ public class Messages {
|
||||
}
|
||||
}
|
||||
|
||||
protected static class TwoStepConfirmationDialog extends MessageDialog {
|
||||
private JCheckBox myCheckBox;
|
||||
private String myCheckboxText;
|
||||
|
||||
public TwoStepConfirmationDialog(String message, String title, String checkboxText, Icon icon) {
|
||||
myCheckboxText = checkboxText;
|
||||
_init(title, message, new String[] {OK_BUTTON, CANCEL_BUTTON}, -1, -1, icon, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createNorthPanel() {
|
||||
JPanel panel = new JPanel(new BorderLayout(15, 0));
|
||||
if (myIcon != null) {
|
||||
JLabel iconLabel = new JLabel(myIcon);
|
||||
Container container = new Container();
|
||||
container.setLayout(new BorderLayout());
|
||||
container.add(iconLabel, BorderLayout.NORTH);
|
||||
panel.add(container, BorderLayout.WEST);
|
||||
}
|
||||
|
||||
JPanel messagePanel = new JPanel(new BorderLayout());
|
||||
if (myMessage != null) {
|
||||
JLabel textLabel = new JLabel(myMessage);
|
||||
textLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
|
||||
textLabel.setUI(new MultiLineLabelUI());
|
||||
messagePanel.add(textLabel, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
final JPanel checkboxPanel = new JPanel();
|
||||
checkboxPanel.setLayout(new BoxLayout(checkboxPanel, BoxLayout.X_AXIS));
|
||||
|
||||
myCheckBox = new JCheckBox(myCheckboxText);
|
||||
myCheckBox.setSelected(true);
|
||||
messagePanel.add(myCheckBox, BorderLayout.SOUTH);
|
||||
panel.add(messagePanel, BorderLayout.CENTER);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExitCode() {
|
||||
final int exitCode = super.getExitCode();
|
||||
return exitCode == OK_EXIT_CODE ? myCheckBox.isSelected() ? OK_EXIT_CODE : CANCEL_EXIT_CODE : CANCEL_EXIT_CODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myCheckBox;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected static class InputDialog extends MessageDialog {
|
||||
private JTextComponent myField;
|
||||
private InputValidator myValidator;
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Registry {
|
||||
|
||||
@@ -35,8 +36,7 @@ public class Registry {
|
||||
|
||||
private final LinkedHashMap<String, String> myUserProperties = new LinkedHashMap<String, String>();
|
||||
private final Map<String, String> myLoadedUserProperties = new HashMap<String, String>();
|
||||
|
||||
private final Map<String, RegistryValue> myValues = new HashMap<String, RegistryValue>();
|
||||
private final Map<String, RegistryValue> myValues = new ConcurrentHashMap<String, RegistryValue>();
|
||||
|
||||
private static final Registry ourInstance = new Registry();
|
||||
|
||||
|
||||
@@ -56,6 +56,11 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
return myParent.getPath() + "/" + myChildName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VirtualFile getFile() {
|
||||
return myParent.findChild(myChildName);
|
||||
}
|
||||
|
||||
public VirtualFileSystem getFileSystem() {
|
||||
return myParent.getFileSystem();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
*/
|
||||
package com.intellij.openapi.vfs.newvfs.events;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class VFileEvent {
|
||||
private final boolean myIsFromRefresh;
|
||||
@@ -40,6 +42,13 @@ public abstract class VFileEvent {
|
||||
|
||||
public abstract String getPath();
|
||||
|
||||
/**
|
||||
* Returns the VirtualFile which this event belongs to.
|
||||
* In some cases it may be null - it is not guaranteed that there is such file.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract VirtualFile getFile();
|
||||
|
||||
public abstract VirtualFileSystem getFileSystem();
|
||||
|
||||
public abstract boolean isValid();
|
||||
|
||||
@@ -171,8 +171,31 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
|
||||
public void paint(Graphics g) {
|
||||
final Rectangle visible = getVisibleRect();
|
||||
|
||||
if (!AbstractTreeBuilder.isToPaintSelection(this)) {
|
||||
mySelectionModel.holdSelection();
|
||||
boolean canHoldSelection = false;
|
||||
TreePath[] paths = getSelectionModel().getSelectionPaths();
|
||||
if (paths != null) {
|
||||
for (TreePath each : paths) {
|
||||
Rectangle selection = getPathBounds(each);
|
||||
if (g.getClipBounds().intersects(selection) || g.getClipBounds().contains(selection)) {
|
||||
if (myBusy) {
|
||||
Rectangle busyIconBounds = myBusyIcon.getBounds();
|
||||
if (selection.contains(busyIconBounds) || selection.intersects(busyIconBounds)) {
|
||||
canHoldSelection = false;
|
||||
break;
|
||||
} else {
|
||||
canHoldSelection = true;
|
||||
}
|
||||
} else {
|
||||
canHoldSelection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canHoldSelection) {
|
||||
if (!AbstractTreeBuilder.isToPaintSelection(this)) {
|
||||
mySelectionModel.holdSelection();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
+56
-28
@@ -121,50 +121,78 @@ class UndoRedoStacksHolder {
|
||||
}
|
||||
|
||||
public void addToStacks(UndoableGroup group) {
|
||||
if (group.isGlobal()) doAddToStack(myGlobalStack, group, UndoManagerImpl.GLOBAL_UNDO_LIMIT);
|
||||
for (DocumentReference each : group.getAffectedDocuments()) {
|
||||
doAddToStack(getStack(each), group, UndoManagerImpl.LOCAL_UNDO_LIMIT);
|
||||
for (LinkedList<UndoableGroup> each : getAffectedStacks(group)) {
|
||||
doAddToStack(each, group, each == myGlobalStack ? UndoManagerImpl.GLOBAL_UNDO_LIMIT : UndoManagerImpl.LOCAL_UNDO_LIMIT);
|
||||
}
|
||||
}
|
||||
|
||||
private void doAddToStack(LinkedList<UndoableGroup> stack, UndoableGroup group, int limit) {
|
||||
if (!group.isUndoable() && stack.isEmpty()) return;
|
||||
|
||||
|
||||
stack.addLast(group);
|
||||
while (stack.size() > limit) {
|
||||
stack.removeFirst();
|
||||
clearStacksFrom(stack.getFirst());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromStacks(UndoableGroup group) {
|
||||
if (group.getAffectedDocuments().isEmpty()) return;
|
||||
|
||||
if (group.isGlobal()) {
|
||||
assert myGlobalStack.getLast() == group;
|
||||
myGlobalStack.removeLast();
|
||||
}
|
||||
for (DocumentReference each : group.getAffectedDocuments()) {
|
||||
LinkedList<UndoableGroup> stack = getStack(each);
|
||||
assert stack.getLast() == group;
|
||||
stack.removeLast();
|
||||
for (LinkedList<UndoableGroup> each : getAffectedStacks(group)) {
|
||||
assert each.getLast() == group;
|
||||
each.removeLast();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearStacks(boolean clearGlobal, Set<DocumentReference> affectedDocuments) {
|
||||
if (clearGlobal) myGlobalStack.clear();
|
||||
for (DocumentReference ref : affectedDocuments) {
|
||||
List<UndoableGroup> stack = getStack(ref);
|
||||
stack.clear();
|
||||
|
||||
if (ref.getFile() != null) {
|
||||
myDocumentStacks.remove(ref);
|
||||
}
|
||||
else {
|
||||
Document d = ref.getDocument();
|
||||
d.putUserData(STACK_IN_DOCUMENT_KEY, null);
|
||||
myDocumentsWithStacks.remove(d);
|
||||
public void clearStacks(boolean clearGlobal, Set<DocumentReference> refs) {
|
||||
for (LinkedList<UndoableGroup> each : getAffectedStacks(clearGlobal, refs)) {
|
||||
while(!each.isEmpty()) {
|
||||
clearStacksFrom(each.getLast());
|
||||
}
|
||||
}
|
||||
|
||||
Set<DocumentReference> stacksToDrop = new THashSet<DocumentReference>();
|
||||
for (Map.Entry<DocumentReference, LinkedList<UndoableGroup>> each : myDocumentStacks.entrySet()) {
|
||||
if (each.getValue().isEmpty()) stacksToDrop.add(each.getKey());
|
||||
}
|
||||
for (DocumentReference each : stacksToDrop) {
|
||||
myDocumentStacks.remove(each);
|
||||
}
|
||||
|
||||
|
||||
Set<Document> docsToDrop = new THashSet<Document>();
|
||||
for (Document each : myDocumentsWithStacks) {
|
||||
LinkedList<UndoableGroup> stack = each.getUserData(STACK_IN_DOCUMENT_KEY);
|
||||
if (stack != null && stack.isEmpty()) {
|
||||
each.putUserData(STACK_IN_DOCUMENT_KEY, null);
|
||||
docsToDrop.add(each);
|
||||
}
|
||||
}
|
||||
myDocumentsWithStacks.removeAll(docsToDrop);
|
||||
}
|
||||
|
||||
private void clearStacksFrom(UndoableGroup from) {
|
||||
for (LinkedList<UndoableGroup> each : getAffectedStacks(from)) {
|
||||
int pos = each.indexOf(from);
|
||||
if (pos == -1) continue;
|
||||
|
||||
if (pos > 0) {
|
||||
int top = each.size() - pos;
|
||||
clearStacksFrom(each.get(pos - 1));
|
||||
assert each.size() == top && each.indexOf(from) == 0;
|
||||
}
|
||||
each.removeFirst();
|
||||
}
|
||||
}
|
||||
|
||||
private List<LinkedList<UndoableGroup>> getAffectedStacks(UndoableGroup group) {
|
||||
return getAffectedStacks(group.isGlobal(), group.getAffectedDocuments());
|
||||
}
|
||||
private List<LinkedList<UndoableGroup>> getAffectedStacks(boolean global, Collection<DocumentReference> refs) {
|
||||
List<LinkedList<UndoableGroup>> result = new ArrayList<LinkedList<UndoableGroup>>();
|
||||
if (global) result.add(myGlobalStack);
|
||||
for (DocumentReference each : refs) {
|
||||
result.add(getStack(each));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void clearAllStacksInTests() {
|
||||
|
||||
@@ -513,6 +513,12 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (myInitialMouseEvent != null) {
|
||||
myIgnoreMouseEventsConsecutiveToInitial = true;
|
||||
}
|
||||
|
||||
// There is a possible case that 'use soft wrap' setting value is changed and we need to repaint all affected lines then.
|
||||
repaintToScreenBottom(getCaretModel().getLogicalPosition().line);
|
||||
int y = getCaretModel().getVisualLineStart() * getLineHeight();
|
||||
myGutterComponent.repaint(0, y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - y);
|
||||
getCaretModel().moveToOffset(getCaretModel().getOffset());
|
||||
}
|
||||
|
||||
private void initTabPainter() {
|
||||
@@ -933,60 +939,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
offset = region.getEndOffset();
|
||||
}
|
||||
else {
|
||||
//SoftWrap softWrap = mySoftWrapModel.getSoftWrap(offset);
|
||||
//if (softWrap != null) {
|
||||
// // There is a possible case that soft wrap contains more than one line feed inside and we need to start counting not
|
||||
// // from its first line.
|
||||
// int softWrapLinesToSkip = activeSoftWrapProcessed ? 0 : logicalPosition.softWrapLinesOnCurrentLogicalLine;
|
||||
//
|
||||
// // Process 'before soft wrap' drawing.
|
||||
// if (softWrapLinesToSkip <= 0) {
|
||||
// prevX = x;
|
||||
// charWidth = getSoftWrapModel().getMinDrawingWidthInPixels(SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED);
|
||||
// x += charWidth;
|
||||
// if (x >= px) {
|
||||
// onSoftWrapDrawing = true;
|
||||
// break outer;
|
||||
// }
|
||||
// column++;
|
||||
// }
|
||||
//
|
||||
// CharSequence softWrapText = softWrap.getText();
|
||||
// for (int i = 0; i < softWrapText.length(); i++) {
|
||||
// c = softWrapText.charAt(i);
|
||||
// if (softWrapLinesToSkip > 0) {
|
||||
// if (c == '\n') {
|
||||
// softWrapLinesToSkip--;
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
// prevX = x;
|
||||
//
|
||||
// charWidth = charToVisibleWidth(c, fontType, x);
|
||||
// if (charWidth == 0) {
|
||||
// charWidth = spaceSize;
|
||||
// break outer;
|
||||
// }
|
||||
//
|
||||
// x += charWidth;
|
||||
// if (x >= px) {
|
||||
// break outer;
|
||||
// }
|
||||
// column += EditorUtil.columnsNumber(c, x, prevX, spaceSize);
|
||||
// }
|
||||
// activeSoftWrapProcessed = true;
|
||||
//
|
||||
// // Process 'after soft wrap' sign.
|
||||
// prevX = x;
|
||||
// charWidth = mySoftWrapModel.getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP);
|
||||
// x += charWidth;
|
||||
// if (x >= px) {
|
||||
// onSoftWrapDrawing = true;
|
||||
// break outer;
|
||||
// }
|
||||
// column++;
|
||||
//}
|
||||
|
||||
prevX = x;
|
||||
c = text.charAt(offset);
|
||||
charWidth = charToVisibleWidth(c, fontType, x);
|
||||
@@ -1091,24 +1043,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
private int logicalToVisualLine(int line) {
|
||||
assertReadAccess();
|
||||
return logicalToVisualPosition(new LogicalPosition(line, 0)).line;
|
||||
//if (!myFoldingModel.isFoldingEnabled()) return line;
|
||||
//
|
||||
//
|
||||
//int offset = line >= myDocument.getLineCount() ? myDocument.getTextLength() : myDocument.getLineStartOffset(line);
|
||||
//
|
||||
//FoldRegion outermostCollapsed = myFoldingModel.getCollapsedRegionAtOffset(offset);
|
||||
//if (outermostCollapsed != null && offset > outermostCollapsed.getStartOffset()) {
|
||||
// if (offset < getDocument().getTextLength()) {
|
||||
// offset = outermostCollapsed.getStartOffset();
|
||||
// return offsetToVisualLine(offset);
|
||||
// }
|
||||
// else {
|
||||
// offset = outermostCollapsed.getEndOffset() + 3; // WTF?
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//line -= myFoldingModel.getFoldedLinesCountBefore(offset);
|
||||
//return line;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1707,6 +1641,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
return;
|
||||
}
|
||||
|
||||
boolean locateBeforeSoftWrap = !SoftWrapHelper.isCaretAfterSoftWrap(this);
|
||||
int start = logicalPositionToOffset(logicalPosition);
|
||||
getSoftWrapModel().registerSoftWrapsIfNecessary(clip, start);
|
||||
|
||||
@@ -1807,22 +1742,21 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
paintAfterFileEndBackground(iterationState, g, position, clip, lineHeight, defaultBackground, caretRowPainted);
|
||||
}
|
||||
|
||||
//TODO den check
|
||||
// Perform additional activity if soft wrap is added or removed during repainting.
|
||||
//if (mySoftWrapsChanged) {
|
||||
// mySoftWrapsChanged = false;
|
||||
// validateSize();
|
||||
//
|
||||
// // Repaint editor to the bottom in order to ensure that its content is shown correctly after new soft wrap introduction.
|
||||
// repaintToScreenBottom(xyToLogicalPosition(position).line);
|
||||
//
|
||||
// // Repaint gutter at all space that is located after active clip in order to ensure that line numbers are correctly redrawn
|
||||
// // in accordance with the newly introduced soft wrap(s).
|
||||
// myGutterComponent.repaint(0, clip.y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - clip.y);
|
||||
//
|
||||
// // Ask caret model to update visual caret position.
|
||||
// getCaretModel().moveToOffset(getCaretModel().getOffset(), locateBeforeSoftWrap);
|
||||
//}
|
||||
if (mySoftWrapsChanged) {
|
||||
mySoftWrapsChanged = false;
|
||||
validateSize();
|
||||
|
||||
// Repaint editor to the bottom in order to ensure that its content is shown correctly after new soft wrap introduction.
|
||||
repaintToScreenBottom(xyToLogicalPosition(position).line);
|
||||
|
||||
// Repaint gutter at all space that is located after active clip in order to ensure that line numbers are correctly redrawn
|
||||
// in accordance with the newly introduced soft wrap(s).
|
||||
myGutterComponent.repaint(0, clip.y, myGutterComponent.getWidth(), myGutterComponent.getHeight() - clip.y);
|
||||
|
||||
// Ask caret model to update visual caret position.
|
||||
getCaretModel().moveToOffset(getCaretModel().getOffset(), locateBeforeSoftWrap);
|
||||
}
|
||||
}
|
||||
|
||||
private void paintRectangularSelection(Graphics g) {
|
||||
@@ -4326,13 +4260,13 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
if (myCommandProcessor != null) {
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
processMousePressed(e, e.getSource() == getContentComponent());
|
||||
processMousePressed(e);
|
||||
}
|
||||
};
|
||||
myCommandProcessor.executeCommand(myProject, runnable, "", DocCommandGroupId.noneGroupId(getDocument()), UndoConfirmationPolicy.DEFAULT, getDocument());
|
||||
}
|
||||
else {
|
||||
processMousePressed(e, e.getSource() == getContentComponent());
|
||||
processMousePressed(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4393,7 +4327,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
}
|
||||
|
||||
private void processMousePressed(MouseEvent e, boolean moveCaretToClickPosition) {
|
||||
private void processMousePressed(MouseEvent e) {
|
||||
myInitialMouseEvent = e;
|
||||
|
||||
if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE && System.currentTimeMillis() - myMouseSelectionChangeTimestamp > 1000) {
|
||||
@@ -4435,9 +4369,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
int oldSelectionStart = mySelectionModel.getLeadSelectionOffset();
|
||||
if (moveCaretToClickPosition) {
|
||||
moveCaretToScreenPos(x, y);
|
||||
}
|
||||
moveCaretToScreenPos(x, y);
|
||||
|
||||
if (e.isPopupTrigger()) return;
|
||||
|
||||
|
||||
@@ -367,7 +367,7 @@ public class FoldingModelImpl implements FoldingModelEx, PrioritizedDocumentList
|
||||
|
||||
myCaretPositionSaved = oldCaretPositionSaved;
|
||||
|
||||
if (!hasBlockSelection) {
|
||||
if (!hasBlockSelection && selectionStart < myEditor.getDocument().getTextLength()) {
|
||||
myEditor.getSelectionModel().setSelection(selectionStart, selectionEnd);
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -438,9 +438,10 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
LOG.info(" documentStamp:" + documentStamp);
|
||||
LOG.info(" oldFileStamp:" + oldFileStamp);
|
||||
|
||||
final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode();
|
||||
Runnable askReloadRunnable = new Runnable() {
|
||||
public void run() {
|
||||
IdeEventQueue.getInstance().removeIdleListener(this);
|
||||
if (!unitTestMode) IdeEventQueue.getInstance().removeIdleListener(this);
|
||||
if (!file.isValid()) return;
|
||||
if (askReloadFromDisk(file, document)) {
|
||||
reloadFromDisk(document);
|
||||
@@ -448,7 +449,11 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
}
|
||||
};
|
||||
|
||||
IdeEventQueue.getInstance().addIdleListener(askReloadRunnable, 2000);
|
||||
if (unitTestMode) {
|
||||
askReloadRunnable.run();
|
||||
} else {
|
||||
IdeEventQueue.getInstance().addIdleListener(askReloadRunnable, 2000);
|
||||
}
|
||||
}
|
||||
else {
|
||||
reloadFromDisk(document);
|
||||
|
||||
+16
@@ -23,8 +23,14 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectLocator;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public class DefaultProjectLocator extends ProjectLocator {
|
||||
@Nullable
|
||||
public Project guessProjectForFile(final VirtualFile file) {
|
||||
@@ -39,4 +45,14 @@ public class DefaultProjectLocator extends ProjectLocator {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<Project> getProjectsForFile(VirtualFile file) {
|
||||
final ProjectManager projectManager = ProjectManager.getInstance();
|
||||
if (projectManager == null || file == null) { return new HashSet<Project>(); }
|
||||
final Project[] openProjects = projectManager.getOpenProjects();
|
||||
return Arrays.asList(openProjects);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -693,7 +693,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
|
||||
message = ProjectBundle.message("project.reload.external.change.multiple", filesBuilder.toString());
|
||||
}
|
||||
|
||||
return Messages.showYesNoDialog(project, message, ProjectBundle.message("project.reload.external.change.title"), Messages.getQuestionIcon()) == 0;
|
||||
return Messages.shpwTwoStepConfirmationDialog(message, ProjectBundle.message("project.reload.external.change.title"), "Reload project", Messages.getQuestionIcon()) == 0;
|
||||
}
|
||||
|
||||
public boolean isFileSavedToBeReloaded(VirtualFile candidate) {
|
||||
|
||||
@@ -37,7 +37,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.border.LineBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.geom.GeneralPath;
|
||||
@@ -234,10 +233,10 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
private void show(PositionTracker<Balloon> tracker, Position position) {
|
||||
if (isVisible()) return;
|
||||
|
||||
assert !myDisposed : "Balloon is already disposed";
|
||||
assert tracker.getComponent().isShowing() : "Target component is not showing: " + tracker;
|
||||
|
||||
if (isVisible()) return;
|
||||
if (!tracker.getComponent().isShowing()) return;
|
||||
|
||||
myTracker = tracker;
|
||||
myTracker.init(this);
|
||||
|
||||
@@ -13,8 +13,8 @@ project.load.undefined.path.variables.all.needed=All path variables should be de
|
||||
project.load.undefined.path.variables.title=Path Variables Not Defined
|
||||
project.load.default.error=Error Loading Default Project
|
||||
project.load.progress=Loading Project
|
||||
project.reload.external.change.single=Project file {0} has been changed externally.\n\nReload project?
|
||||
project.reload.external.change.multiple=Project files:\n{0}\nhave been changed externally.\n\nReload project?
|
||||
project.reload.external.change.single=Project file {0} has been changed externally.\nIt is recommended to reload project for changes to take effect.
|
||||
project.reload.external.change.multiple=Project files:\n{0}\nhave been changed externally.\nIt is recommended to reload project for changes to take effect.
|
||||
project.reload.external.change.title=Project Files Changed
|
||||
project.reload.write.failed=Error writing to file ''{0}''. Project may reload incorrectly.
|
||||
project.reload.write.failed.title=Write error
|
||||
|
||||
@@ -181,13 +181,23 @@ public class AbstractVcsTestCase {
|
||||
return result.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates directory inside a write action and returns the resulting reference to it.
|
||||
* If the directory already exists, does nothing.
|
||||
* @param parent Parent directory.
|
||||
* @param name Name of the directory.
|
||||
* @return reference to the created or already existing directory.
|
||||
*/
|
||||
protected VirtualFile createDirInCommand(final VirtualFile parent, final String name) {
|
||||
final Ref<VirtualFile> result = new Ref<VirtualFile>();
|
||||
new WriteCommandAction.Simple(myProject) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
try {
|
||||
VirtualFile dir = parent.createChildDirectory(this, name);
|
||||
VirtualFile dir = parent.findChild(name);
|
||||
if (dir == null) {
|
||||
dir = parent.createChildDirectory(this, name);
|
||||
}
|
||||
result.set(dir);
|
||||
}
|
||||
catch (IOException e) {
|
||||
@@ -317,6 +327,10 @@ public class AbstractVcsTestCase {
|
||||
}.execute();
|
||||
}
|
||||
|
||||
protected void editFileInCommand(final VirtualFile file, final String newContent) {
|
||||
editFileInCommand(myProject, file, newContent);
|
||||
}
|
||||
|
||||
public static void editFileInCommand(final Project project, final VirtualFile file, final String newContent) {
|
||||
new WriteCommandAction.Simple(project) {
|
||||
@Override
|
||||
|
||||
+8
@@ -1060,6 +1060,14 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
|
||||
myProjectFixture.tearDown();
|
||||
myTempDirFixture.tearDown();
|
||||
|
||||
myEditor = null;
|
||||
myFile = null;
|
||||
myPsiManager = null;
|
||||
myInspections = null;
|
||||
myAvailableLocalTools.clear();
|
||||
myAvailableTools.clear();
|
||||
myFileContext = null;
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import dk.brics.automaton.Automaton;
|
||||
import dk.brics.automaton.DatatypesAutomatonProvider;
|
||||
import dk.brics.automaton.RegExp;
|
||||
import dk.brics.automaton.RunAutomaton;
|
||||
import org.apache.oro.text.regex.MalformedPatternException;
|
||||
import org.apache.oro.text.regex.Pattern;
|
||||
import org.apache.oro.text.regex.Perl5Compiler;
|
||||
import org.apache.oro.text.regex.Perl5Matcher;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -384,17 +384,19 @@ public class NameUtil {
|
||||
private static class OptimizedMatcher implements Matcher {
|
||||
private final char[] myPreparedPattern;
|
||||
private final boolean myEnsureFirstSymbolsMatch;
|
||||
private final RunAutomaton myRunAutomaton;
|
||||
private final Perl5Matcher myMatcher;
|
||||
private final Pattern myPattern;
|
||||
|
||||
public OptimizedMatcher(String pattern, String regexp) {
|
||||
myPreparedPattern = preparePattern(pattern).toCharArray();
|
||||
myEnsureFirstSymbolsMatch = pattern.length() > 0 && Character.isLetterOrDigit(pattern.charAt(0));
|
||||
|
||||
//final long t = System.currentTimeMillis();
|
||||
final RegExp regExp = new RegExp(regexp);
|
||||
final Automaton automaton = regExp.toAutomaton(new DatatypesAutomatonProvider());
|
||||
myRunAutomaton = new RunAutomaton(automaton, true);
|
||||
//System.out.println("t = " + (System.currentTimeMillis() - t));
|
||||
try {
|
||||
myPattern = new Perl5Compiler().compile(regexp);
|
||||
}
|
||||
catch (MalformedPatternException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
myMatcher = new Perl5Matcher();
|
||||
}
|
||||
|
||||
public boolean matches(String name) {
|
||||
@@ -402,7 +404,7 @@ public class NameUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
return myRunAutomaton.run(name);
|
||||
return myMatcher.matches(name, myPattern);
|
||||
}
|
||||
|
||||
private static String preparePattern(String pattern) {
|
||||
|
||||
+1
-11
@@ -16,18 +16,8 @@
|
||||
<orderEntry type="module" module-name="platform-resources-en" />
|
||||
<orderEntry type="module" module-name="annotations" exported="" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../../lib/automaton.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$MODULE_DIR$/../../lib/src/automaton-1.11.zip!/src" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="jna" level="project" />
|
||||
<orderEntry type="library" name="OroMatcher" level="project" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
|
||||
+62
-43
@@ -28,10 +28,12 @@ import com.intellij.openapi.vfs.newvfs.events.*;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -68,62 +70,50 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
|
||||
final FileAndDirsCollector dirtyFilesAndDirs = new FileAndDirsCollector();
|
||||
// collect files and directories - sources of events
|
||||
for (VFileEvent event : events) {
|
||||
final String path = event.getPath();
|
||||
final VirtualFile file = getFileForEvent(event);
|
||||
if (file == null) { continue; }
|
||||
|
||||
if (event instanceof VFileDeleteEvent) {
|
||||
final VirtualFile file = ((VFileDeleteEvent)event).getFile();
|
||||
if (!file.isInLocalFileSystem()) { return; }
|
||||
if (!file.isInLocalFileSystem()) { continue; }
|
||||
dirtyFilesAndDirs.add(file);
|
||||
} else if (event instanceof VFileMoveEvent) {
|
||||
final VirtualFile file = ((VFileMoveEvent)event).getFile();
|
||||
dirtyFilesAndDirs.addToFiles(file);
|
||||
} else if (event instanceof VFilePropertyChangeEvent) {
|
||||
final VirtualFile file = ((VFilePropertyChangeEvent)event).getFile();
|
||||
} else if (event instanceof VFileMoveEvent || event instanceof VFilePropertyChangeEvent) {
|
||||
dirtyFilesAndDirs.addToFiles(file);
|
||||
}
|
||||
}
|
||||
// and notify VCSDirtyScopeManager
|
||||
dirtyFilesAndDirs.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void after(List<? extends VFileEvent> events) {
|
||||
final FileAndDirsCollector dirtyFilesAndDirs = new FileAndDirsCollector();
|
||||
|
||||
// collect files and directories - sources of events
|
||||
for (VFileEvent event : events) {
|
||||
if (event instanceof VFileContentChangeEvent) {
|
||||
final VirtualFile file = ((VFileContentChangeEvent)event).getFile();
|
||||
final VirtualFile file = getFileForEvent(event);
|
||||
if (file == null) { continue; }
|
||||
|
||||
if (event instanceof VFileContentChangeEvent || event instanceof VFileCopyEvent || event instanceof VFileCreateEvent) {
|
||||
dirtyFilesAndDirs.addToFiles(file);
|
||||
} else if (event instanceof VFileCopyEvent) {
|
||||
final VirtualFile file = ((VFileCopyEvent)event).getFile();
|
||||
dirtyFilesAndDirs.addToFiles(file);
|
||||
} else if (event instanceof VFileCreateEvent) {
|
||||
final VFileCreateEvent ce = ((VFileCreateEvent)event);
|
||||
final VirtualFile file = ce.getParent().findChild(ce.getChildName());
|
||||
dirtyFilesAndDirs.addToFiles(file);
|
||||
} else if (event instanceof VFileMoveEvent) {
|
||||
dirtyFilesAndDirs.add(((VFileMoveEvent)event).getFile());
|
||||
} else if (event instanceof VFilePropertyChangeEvent) {
|
||||
final VFilePropertyChangeEvent pce = (VFilePropertyChangeEvent) event;
|
||||
VirtualFile file = pce.getFile();
|
||||
// if file was renamed, then mark dirty the file and its parent directory
|
||||
|
||||
if (pce.getPropertyName().equals(VirtualFile.PROP_NAME)) {
|
||||
if (file.getParent() != null) {
|
||||
file = file.getParent();
|
||||
}
|
||||
dirtyFilesAndDirs.add(file);
|
||||
// if a file was renamed, then the file is dirty and its parent directory is dirty too;
|
||||
// if a directory was renamed, all its children are recursively dirty, the parent dir is also dirty but not recursively.
|
||||
dirtyFilesAndDirs.add(file); // the file is dirty recursively
|
||||
dirtyFilesAndDirs.addToFiles(file.getParent()); // directory is dirty alone. if parent is null - is checked in the method
|
||||
} else {
|
||||
dirtyFilesAndDirs.addToFiles(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
// and notify VCSDirtyScopeManager
|
||||
dirtyFilesAndDirs.markDirty();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VcsDirtyScopeManager getManager(final VirtualFile file) {
|
||||
if (file == null) { return null; }
|
||||
final Project project = myProjectLocator.guessProjectForFile(file);
|
||||
if (project == null) { return null; }
|
||||
return VcsDirtyScopeManager.getInstance(project);
|
||||
private static VirtualFile getFileForEvent(VFileEvent event) {
|
||||
return VcsUtil.getVirtualFile(event.getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,28 +134,38 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
|
||||
* @param addToFiles If true, then add to dirty files even if it is a directory. Otherwise add to the proper set.
|
||||
*/
|
||||
private void add(VirtualFile file, boolean addToFiles) {
|
||||
final VcsDirtyScopeManager manager = getManager(file);
|
||||
if (manager == null) { return; }
|
||||
Pair<HashSet<FilePath>, HashSet<FilePath>> filesAndDirs = map.get(manager);
|
||||
if (filesAndDirs == null) {
|
||||
filesAndDirs = Pair.create(new HashSet<FilePath>(), new HashSet<FilePath>());
|
||||
map.put(manager, filesAndDirs);
|
||||
}
|
||||
|
||||
if (file == null) { return; }
|
||||
final boolean isDirectory = file.isDirectory();
|
||||
// need to create FilePath explicitly without referring to VirtualFile because the path of VirtualFile may change
|
||||
final FilePathImpl path = new FilePathImpl(new File(file.getPath()), isDirectory);
|
||||
if (addToFiles || isDirectory) {
|
||||
filesAndDirs.first.add(path);
|
||||
} else {
|
||||
filesAndDirs.second.add(path);
|
||||
|
||||
final Collection<VcsDirtyScopeManager> managers = getManagers(file);
|
||||
for (VcsDirtyScopeManager manager : managers) {
|
||||
Pair<HashSet<FilePath>, HashSet<FilePath>> filesAndDirs = map.get(manager);
|
||||
if (filesAndDirs == null) {
|
||||
filesAndDirs = Pair.create(new HashSet<FilePath>(), new HashSet<FilePath>());
|
||||
map.put(manager, filesAndDirs);
|
||||
}
|
||||
|
||||
if (addToFiles || !isDirectory) {
|
||||
filesAndDirs.first.add(path);
|
||||
} else {
|
||||
filesAndDirs.second.add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds files to the collection of files and directories - to the collection of directories (which are handled recursively).
|
||||
*/
|
||||
void add(VirtualFile file) {
|
||||
add(file, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds to the collection of files. A file (even if it is a directory) is marked dirty alone (not recursively).
|
||||
* Use this method, when you want directory not to be marked dirty recursively.
|
||||
*/
|
||||
void addToFiles(VirtualFile file) {
|
||||
add(file, true);
|
||||
}
|
||||
@@ -180,4 +180,23 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all VcsDirtyScopeManagers which serve the given file.
|
||||
* There may be none of them or there may be several (if a file is contained in several open projects, for instance),
|
||||
* though usually there is one.
|
||||
*/
|
||||
@NotNull
|
||||
private Collection<VcsDirtyScopeManager> getManagers(final VirtualFile file) {
|
||||
final Collection<VcsDirtyScopeManager> result = new HashSet<VcsDirtyScopeManager>();
|
||||
if (file == null) { return result; }
|
||||
final Collection<Project> projects = myProjectLocator.getProjectsForFile(file);
|
||||
for (Project project : projects) {
|
||||
final VcsDirtyScopeManager manager = VcsDirtyScopeManager.getInstance(project);
|
||||
if (manager != null) {
|
||||
result.add(manager);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1768,6 +1768,7 @@ ignore.single.field.static.imports.option=Ignore single &field static imports
|
||||
ignore.single.method.static.imports.option=Ignore single &method static imports
|
||||
ignore.methods.with.boolean.return.type.option=Ignore methods with &Boolean return type
|
||||
ignore.boolean.methods.in.an.interface.option=Ignore boolean methods in an @&interface
|
||||
ignore.methods.overriding.super.method=Ignore methods &overriding a super method
|
||||
ignored.io.resource.types=Ignored I/O resource types
|
||||
choose.io.resource.type.to.ignore=Choose I/O resource type to ignore
|
||||
ignore.accesses.from.the.same.class=ignore accesses from the same class
|
||||
|
||||
+33
-27
@@ -15,23 +15,26 @@
|
||||
*/
|
||||
package com.siyeh.ig.naming;
|
||||
|
||||
import com.intellij.codeInspection.ui.AddAction;
|
||||
import com.intellij.codeInspection.ui.ListTable;
|
||||
import com.intellij.codeInspection.ui.ListWrappingTableModel;
|
||||
import com.intellij.codeInspection.ui.RemoveAction;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.util.Query;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.fixes.RenameFix;
|
||||
import com.siyeh.ig.psiutils.LibraryUtil;
|
||||
import com.siyeh.ig.ui.*;
|
||||
import com.siyeh.ig.ui.CheckBox;
|
||||
import com.siyeh.ig.ui.UiUtils;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -50,6 +53,9 @@ public class BooleanMethodNameMustStartWithQuestionInspection
|
||||
@SuppressWarnings({"PublicField"})
|
||||
public boolean ignoreInAnnotationInterface = true;
|
||||
|
||||
@SuppressWarnings({"PublicField"})
|
||||
public boolean onlyWarnOnBaseMethods = true;
|
||||
|
||||
/** @noinspection PublicField*/
|
||||
@NonNls public String questionString =
|
||||
"is,can,has,should,could,will,shall,check,contains,equals,add," +
|
||||
@@ -94,41 +100,28 @@ public class BooleanMethodNameMustStartWithQuestionInspection
|
||||
new ListTable(new ListWrappingTableModel(questionList,
|
||||
InspectionGadgetsBundle.message(
|
||||
"boolean.method.name.must.start.with.question.table.column.name")));
|
||||
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table);
|
||||
final JScrollPane scrollPane =
|
||||
ScrollPaneFactory.createScrollPane(table);
|
||||
final ActionToolbar toolbar =
|
||||
UiUtils.createAddRemoveToolbar(table);
|
||||
|
||||
final GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy = 0;
|
||||
constraints.gridheight = 3;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel.add(toolbar.getComponent(), constraints);
|
||||
|
||||
constraints.gridy = 1;
|
||||
constraints.weightx = 1.0;
|
||||
constraints.weighty = 1.0;
|
||||
constraints.fill = GridBagConstraints.BOTH;
|
||||
panel.add(scrollPane, constraints);
|
||||
|
||||
final JButton addButton = new JButton(new AddAction(table));
|
||||
constraints.gridx = 1;
|
||||
constraints.gridheight = 1;
|
||||
constraints.weightx = 0.0;
|
||||
constraints.weighty = 0.0;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel.add(addButton, constraints);
|
||||
|
||||
final JButton removeButton = new JButton(new RemoveAction(table));
|
||||
constraints.gridy = 1;
|
||||
panel.add(removeButton, constraints);
|
||||
|
||||
final BlankFiller filler = new BlankFiller();
|
||||
constraints.gridy = 2;
|
||||
constraints.weighty = 1.0;
|
||||
panel.add(filler, constraints);
|
||||
|
||||
final CheckBox checkBox1 =
|
||||
new CheckBox(InspectionGadgetsBundle.message(
|
||||
"ignore.methods.with.boolean.return.type.option"),
|
||||
this, "ignoreBooleanMethods");
|
||||
constraints.gridy = 3;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridwidth = 2;
|
||||
constraints.gridy = 2;
|
||||
constraints.weighty = 0.0;
|
||||
panel.add(checkBox1, constraints);
|
||||
|
||||
@@ -136,8 +129,15 @@ public class BooleanMethodNameMustStartWithQuestionInspection
|
||||
new CheckBox(InspectionGadgetsBundle.message(
|
||||
"ignore.boolean.methods.in.an.interface.option"),
|
||||
this, "ignoreInAnnotationInterface");
|
||||
constraints.gridy = 4;
|
||||
constraints.gridy = 3;
|
||||
panel.add(checkBox2, constraints);
|
||||
|
||||
final CheckBox checkBox3 =
|
||||
new CheckBox(InspectionGadgetsBundle.message(
|
||||
"ignore.methods.overriding.super.method"),
|
||||
this, "onlyWarnOnBaseMethods");
|
||||
constraints.gridy = 4;
|
||||
panel.add(checkBox3, constraints);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,13 @@ public class BooleanMethodNameMustStartWithQuestionInspection
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(LibraryUtil.isOverrideOfLibraryMethod(method)){
|
||||
if (onlyWarnOnBaseMethods) {
|
||||
final Query<MethodSignatureBackedByPsiMethod> superSearch =
|
||||
SuperMethodsSearch.search(method, null, true, false);
|
||||
if (superSearch.findFirst() != null) {
|
||||
return;
|
||||
}
|
||||
} else if (LibraryUtil.isOverrideOfLibraryMethod(method)) {
|
||||
return;
|
||||
}
|
||||
registerMethodError(method);
|
||||
|
||||
+36
-29
@@ -15,22 +15,25 @@
|
||||
*/
|
||||
package com.siyeh.ig.naming;
|
||||
|
||||
import com.intellij.codeInspection.ui.AddAction;
|
||||
import com.intellij.codeInspection.ui.ListTable;
|
||||
import com.intellij.codeInspection.ui.ListWrappingTableModel;
|
||||
import com.intellij.codeInspection.ui.RemoveAction;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.util.Query;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.fixes.RenameFix;
|
||||
import com.siyeh.ig.psiutils.LibraryUtil;
|
||||
import com.siyeh.ig.ui.*;
|
||||
import com.siyeh.ig.ui.CheckBox;
|
||||
import com.siyeh.ig.ui.UiUtils;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -51,6 +54,9 @@ public class NonBooleanMethodNameMayNotStartWithQuestionInspection
|
||||
@SuppressWarnings({"PublicField"})
|
||||
public boolean ignoreBooleanMethods = false;
|
||||
|
||||
@SuppressWarnings({"PublicField"})
|
||||
public boolean onlyWarnOnBaseMethods = true;
|
||||
|
||||
List<String> questionList = new ArrayList(32);
|
||||
|
||||
public NonBooleanMethodNameMayNotStartWithQuestionInspection(){
|
||||
@@ -90,43 +96,36 @@ public class NonBooleanMethodNameMayNotStartWithQuestionInspection
|
||||
new ListTable(new ListWrappingTableModel(questionList,
|
||||
InspectionGadgetsBundle.message(
|
||||
"boolean.method.name.must.start.with.question.table.column.name")));
|
||||
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table);
|
||||
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table);
|
||||
|
||||
final ActionToolbar toolbar =
|
||||
UiUtils.createAddRemoveToolbar(table);
|
||||
final GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy = 0;
|
||||
constraints.gridheight = 3;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel.add(toolbar.getComponent(), constraints);
|
||||
|
||||
constraints.gridy = 1;
|
||||
constraints.weightx = 1.0;
|
||||
constraints.weighty = 1.0;
|
||||
constraints.fill = GridBagConstraints.BOTH;
|
||||
panel.add(scrollPane, constraints);
|
||||
|
||||
final JButton addButton = new JButton(new AddAction(table));
|
||||
constraints.gridx = 1;
|
||||
constraints.gridheight = 1;
|
||||
constraints.weightx = 0.0;
|
||||
constraints.weighty = 0.0;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel.add(addButton, constraints);
|
||||
|
||||
final JButton removeButton = new JButton(new RemoveAction(table));
|
||||
constraints.gridy = 1;
|
||||
panel.add(removeButton, constraints);
|
||||
|
||||
final BlankFiller filler = new BlankFiller();
|
||||
constraints.gridy = 2;
|
||||
constraints.weighty = 1.0;
|
||||
panel.add(filler, constraints);
|
||||
|
||||
final CheckBox checkBox =
|
||||
final CheckBox checkBox1 =
|
||||
new CheckBox(InspectionGadgetsBundle.message(
|
||||
"ignore.methods.with.boolean.return.type.option"),
|
||||
this, "ignoreBooleanMethods");
|
||||
constraints.gridy = 3;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridwidth = 2;
|
||||
constraints.gridy = 2;
|
||||
constraints.weighty = 0.0;
|
||||
panel.add(checkBox, constraints);
|
||||
panel.add(checkBox1, constraints);
|
||||
|
||||
final CheckBox checkBox2 =
|
||||
new CheckBox(InspectionGadgetsBundle.message(
|
||||
"ignore.methods.overriding.super.method"),
|
||||
this, "onlyWarnOnBaseMethods");
|
||||
constraints.gridy = 3;
|
||||
panel.add(checkBox2, constraints);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -173,8 +172,16 @@ public class NonBooleanMethodNameMayNotStartWithQuestionInspection
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!startsWithQuestionWord ||
|
||||
LibraryUtil.isOverrideOfLibraryMethod(method)){
|
||||
if(!startsWithQuestionWord){
|
||||
return;
|
||||
}
|
||||
if (onlyWarnOnBaseMethods) {
|
||||
final Query<MethodSignatureBackedByPsiMethod> superSearch =
|
||||
SuperMethodsSearch.search(method, null, true, false);
|
||||
if (superSearch.findFirst() != null) {
|
||||
return;
|
||||
}
|
||||
} else if (LibraryUtil.isOverrideOfLibraryMethod(method)) {
|
||||
return;
|
||||
}
|
||||
registerMethodError(method);
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.siyeh.ig.naming.QuestionableNameInspection.Form">
|
||||
<grid id="f9915" binding="contentPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="4" vgap="4">
|
||||
<margin top="4" left="4" bottom="4" right="4"/>
|
||||
<constraints>
|
||||
<xy x="94" y="35" width="282" height="158"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<scrollpane class="com.intellij.ui.components.JBScrollPane" id="14807">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="47930" class="com.intellij.codeInspection.ui.ListTable" binding="table" custom-create="true">
|
||||
<constraints/>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="52926" class="javax.swing.JButton" binding="addButton">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<margin top="3" left="8" bottom="3" right="8"/>
|
||||
<text resource-bundle="com/siyeh/InspectionGadgetsBundle" key="button.add"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f6174" class="javax.swing.JButton" binding="removeButton">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<margin top="3" left="8" bottom="3" right="8"/>
|
||||
<text resource-bundle="com/siyeh/InspectionGadgetsBundle" key="button.remove"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="f3a31">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,25 +15,27 @@
|
||||
*/
|
||||
package com.siyeh.ig.naming;
|
||||
|
||||
import com.intellij.codeInspection.ui.RemoveAction;
|
||||
import com.intellij.codeInspection.ui.ListTable;
|
||||
import com.intellij.codeInspection.ui.ListWrappingTableModel;
|
||||
import com.intellij.openapi.actionSystem.ActionToolbar;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.fixes.RenameFix;
|
||||
import com.intellij.codeInspection.ui.AddAction;
|
||||
import com.intellij.codeInspection.ui.ListTable;
|
||||
import com.intellij.codeInspection.ui.ListWrappingTableModel;
|
||||
import com.siyeh.ig.ui.UiUtils;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -54,41 +56,69 @@ public class QuestionableNameInspection extends BaseInspection {
|
||||
parseString(nameString, nameList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName(){
|
||||
return InspectionGadgetsBundle.message(
|
||||
"questionable.name.display.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String buildErrorString(Object... infos){
|
||||
return InspectionGadgetsBundle.message(
|
||||
"questionable.name.problem.descriptor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSettings(Element element) throws InvalidDataException{
|
||||
super.readSettings(element);
|
||||
parseString(nameString, nameList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSettings(Element element) throws WriteExternalException{
|
||||
nameString = formatString(nameList);
|
||||
super.writeSettings(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createOptionsPanel(){
|
||||
final Form form = new Form();
|
||||
return form.getContentPanel();
|
||||
final JPanel panel = new JPanel(new GridBagLayout());
|
||||
final ListTable table = new ListTable(new ListWrappingTableModel(
|
||||
nameList, InspectionGadgetsBundle.message(
|
||||
"questionable.name.column.title")));
|
||||
final JScrollPane scrollPane =
|
||||
ScrollPaneFactory.createScrollPane(table);
|
||||
final ActionToolbar toolbar =
|
||||
UiUtils.createAddRemoveToolbar(table);
|
||||
|
||||
final GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy = 0;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
panel.add(toolbar.getComponent(), constraints);
|
||||
|
||||
constraints.gridy = 1;
|
||||
constraints.weightx = 1.0;
|
||||
constraints.weighty = 1.0;
|
||||
constraints.fill = GridBagConstraints.BOTH;
|
||||
panel.add(scrollPane, constraints);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InspectionGadgetsFix buildFix(Object... infos){
|
||||
return new RenameFix();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean buildQuickFixesOnlyForOnTheFlyErrors(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor(){
|
||||
return new QuestionableNameVisitor();
|
||||
}
|
||||
@@ -118,28 +148,4 @@ public class QuestionableNameInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Form{
|
||||
|
||||
JPanel contentPanel;
|
||||
JButton addButton;
|
||||
JButton removeButton;
|
||||
ListTable table;
|
||||
|
||||
Form(){
|
||||
super();
|
||||
addButton.setAction(new AddAction(table));
|
||||
removeButton.setAction(new RemoveAction(table));
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
table = new ListTable(new ListWrappingTableModel(
|
||||
nameList, InspectionGadgetsBundle.message(
|
||||
"questionable.name.column.title")));
|
||||
}
|
||||
|
||||
public JComponent getContentPanel(){
|
||||
return contentPanel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.tests;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.FilePathImpl;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.changes.VcsAppendableDirtyScope;
|
||||
import com.intellij.openapi.vcs.changes.VcsDirtyScopeImpl;
|
||||
import com.intellij.openapi.vcs.changes.pending.MockChangeListManagerGate;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.vcs.MockChangelistBuilder;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import git4idea.GitVcs;
|
||||
import git4idea.changes.GitChangeProvider;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.openapi.vcs.FileStatus.ADDED;
|
||||
import static com.intellij.openapi.vcs.FileStatus.MODIFIED;
|
||||
import static com.intellij.openapi.vcs.FileStatus.DELETED;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests GitChangeProvider functionality. Scenario is the same for all tests:
|
||||
* 1. Modifies files on disk (creates, edits, deletes, etc.)
|
||||
* 2. Manually adds them to a dirty scope (better to use VcsDirtyScopeManagerImpl, but it's too asynchronous - couldn't overcome this for now.
|
||||
* 3. Calls ChangeProvider.getChanges() and checks that the changes are there.
|
||||
* TODO: change VirtualFile to FilePath or path declared by String - and add tests on move etc. Otherwise VirtualFile is not fuctional for move and harder to test deletes.
|
||||
* TODO: there is almost nothing special about git. Expand to all version controls. But beware that tests should be modified on VCs which track directories.
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public class GitChangeProviderTest extends GitTestCase {
|
||||
|
||||
private GitChangeProvider myChangeProvider;
|
||||
private VcsAppendableDirtyScope myDirtyScope;
|
||||
private Map<String, VirtualFile> myFiles;
|
||||
private VirtualFile afile;
|
||||
|
||||
@BeforeMethod
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myChangeProvider = (GitChangeProvider) GitVcs.getInstance(myProject).getChangeProvider();
|
||||
myDirtyScope = new VcsDirtyScopeImpl(GitVcs.getInstance(myProject), myProject);
|
||||
|
||||
myFiles = createFileStructure("a.txt", "b.txt", "dir/c.txt", "dir/subdir/d.txt");
|
||||
afile = myFiles.get("a.txt"); // the file is commonly used, so save it in a field.
|
||||
myRepo.commit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFile() throws Exception {
|
||||
VirtualFile bfile = myRepo.createFile("new.txt");
|
||||
assertChanges(bfile, ADDED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFileInDir() throws Exception {
|
||||
VirtualFile dir = createDirInCommand(myRepo.getDir(), "newdir");
|
||||
VirtualFile bfile = createFileInCommand(dir, "new.txt", "initial b");
|
||||
assertChanges(new VirtualFile[] {bfile, dir}, new FileStatus[] { ADDED, null} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEditFile() throws Exception {
|
||||
editFileInCommand(afile, "new content");
|
||||
assertChanges(afile, MODIFIED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteFile() throws Exception {
|
||||
deleteFileInCommand(afile);
|
||||
assertChanges(afile, DELETED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDirRecursively() throws Exception {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override public void run() {
|
||||
FileUtil.delete(new File(myRepo.getDir().getPath(), "dir"));
|
||||
}
|
||||
});
|
||||
assertChanges(new VirtualFile[] { myFiles.get("dir/c.txt"), myFiles.get("dir/subdir/d.txt") }, new FileStatus[] { DELETED, DELETED });
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimultaneousOperationsOnMultipleFiles() throws Exception {
|
||||
VirtualFile dfile = myFiles.get("dir/subdir/d.txt");
|
||||
VirtualFile cfile = myFiles.get("dir/c.txt");
|
||||
|
||||
editFileInCommand(afile, "new content");
|
||||
editFileInCommand(cfile, "new content");
|
||||
deleteFileInCommand(dfile);
|
||||
VirtualFile newfile = createFileInCommand("newfile.txt", "new content");
|
||||
|
||||
assertChanges(new VirtualFile[] {afile, cfile, dfile, newfile}, new FileStatus[] {MODIFIED, MODIFIED, DELETED, ADDED});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the given files have respective statuses in the change list retrieved from myChangesProvider.
|
||||
* Pass null in the fileStatuses array to indicate that proper file has not changed.
|
||||
*/
|
||||
private void assertChanges(VirtualFile[] virtualFiles, FileStatus[] fileStatuses) throws VcsException {
|
||||
Map<VirtualFile, Change> result = getChanges(virtualFiles);
|
||||
for (int i = 0; i < virtualFiles.length; i++) {
|
||||
VirtualFile vf = virtualFiles[i];
|
||||
FileStatus status = fileStatuses[i];
|
||||
if (status == null) {
|
||||
assertFalse(result.containsKey(vf), "File [" + vf + " shouldn't be in the change list, but it was.");
|
||||
continue;
|
||||
}
|
||||
assertTrue(result.containsKey(vf), "File [" + vf + "] didn't change. Changes: " + result);
|
||||
assertEquals(result.get(vf).getFileStatus(), status, "File statuses don't match for file [" + vf + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private void assertChanges(VirtualFile virtualFile, FileStatus fileStatus) throws VcsException {
|
||||
assertChanges(new VirtualFile[] { virtualFile }, new FileStatus[] { fileStatus });
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given files dirty in myDirtyScope, gets changes from myChangeProvider and groups the changes in the map.
|
||||
* Assumes that only one change for a file happened.
|
||||
*/
|
||||
private Map<VirtualFile, Change> getChanges(VirtualFile... changedFiles) throws VcsException {
|
||||
// populate dirty scope
|
||||
for (VirtualFile vf : changedFiles) {
|
||||
myDirtyScope.addDirtyFile(new FilePathImpl(vf));
|
||||
}
|
||||
|
||||
// get changes
|
||||
MockChangelistBuilder builder = new MockChangelistBuilder();
|
||||
myChangeProvider.getChanges(myDirtyScope, builder, new EmptyProgressIndicator(), new MockChangeListManagerGate(ChangeListManager.getInstance(myProject)));
|
||||
List<Change> changes = builder.getChanges();
|
||||
|
||||
// get changes for files
|
||||
Map<VirtualFile, Change> result = new HashMap<VirtualFile, Change>();
|
||||
for (Change change : changes) {
|
||||
VirtualFile file = change.getVirtualFile();
|
||||
if (file == null) { // if a file was deleted, just find the reference in the original list of files and use it.
|
||||
String path = change.getBeforeRevision().getFile().getPath();
|
||||
for (VirtualFile vf : changedFiles) {
|
||||
if (vf.getPath().equals(path)) {
|
||||
file = vf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.put(file, change);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates file structure for given paths. Path element should be a relative (from project root)
|
||||
* path to a file or a directory. All intermediate paths will be created if needed.
|
||||
* To create a dir without creating a file pass "dir/" as a parameter.</p>
|
||||
* <p>Usage example:
|
||||
* <code>createFileStructure("a.txt", "b.txt", "dir/c.txt", "dir/subdir/d.txt", "anotherdir/");</code></p>
|
||||
* <p>This will create files a.txt and b.txt in the project dir, create directories dir, dir/subdir and anotherdir,
|
||||
* and create file c.txt in dir and d.txt in dir/subdir.</p>
|
||||
* <p>Note: use forward slash to denote directories, even if it is backslash that separates dirs in your system.</p>
|
||||
* <p>All files are populated with "initial content" string.</p>
|
||||
*/
|
||||
private Map<String, VirtualFile> createFileStructure(String... paths) {
|
||||
Map<String, VirtualFile> result = new HashMap<String, VirtualFile>();
|
||||
|
||||
for (String path : paths) {
|
||||
String[] pathElements = path.split("/");
|
||||
boolean lastIsDir = path.endsWith("/");
|
||||
VirtualFile currentParent = myRepo.getDir();
|
||||
for (int i = 0; i < pathElements.length-1; i++) {
|
||||
currentParent = createDirInCommand(currentParent, pathElements[i]);
|
||||
}
|
||||
|
||||
String lastElement = pathElements[pathElements.length-1];
|
||||
currentParent = lastIsDir ? createDirInCommand(currentParent, lastElement) : createFileInCommand(currentParent, lastElement, "initial content");
|
||||
result.put(path, currentParent);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,7 +23,6 @@ import com.intellij.openapi.vcs.VcsShowConfirmationOption;
|
||||
import com.intellij.testFramework.AbstractVcsTestCase;
|
||||
import git4idea.GitVcs;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
package git4idea.tests;
|
||||
|
||||
import com.intellij.execution.process.ProcessOutput;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.testFramework.AbstractVcsTestCase;
|
||||
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
|
||||
@@ -24,6 +27,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* Representation of a Git repository for tests purposes.
|
||||
@@ -87,56 +91,83 @@ public class GitTestRepository {
|
||||
}
|
||||
|
||||
/**
|
||||
* Natively executes the given mercurial command.
|
||||
* Natively executes the given mercurial command inside write or read action.
|
||||
* @param writeAction If true, the command will be executed in a write action, otherwise - inside a read action.
|
||||
* @param commandWithParameters Mercurial command with parameters. E.g. ["status", "-a"]
|
||||
*/
|
||||
public ProcessOutput execute(String... commandWithParameters) throws IOException {
|
||||
return myTest.executeCommand(new File(myDirFixture.getTempDirPath()), commandWithParameters);
|
||||
public ProcessOutput execute(boolean writeAction, final String... commandWithParameters) throws IOException {
|
||||
final AtomicReference<ProcessOutput> result = new AtomicReference<ProcessOutput>();
|
||||
final Runnable action = new Runnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
result.set(myTest.executeCommand(new File(myDirFixture.getTempDirPath()), commandWithParameters));
|
||||
} catch (IOException e) {
|
||||
result.set(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (ApplicationManager.getApplication() == null) { // application may be not initialized yet. OK to just run the action then.
|
||||
action.run();
|
||||
return result.get();
|
||||
}
|
||||
if (writeAction) {
|
||||
ApplicationManager.getApplication().runWriteAction(action);
|
||||
} else {
|
||||
ApplicationManager.getApplication().runReadAction(action);
|
||||
}
|
||||
return result.get();
|
||||
}
|
||||
|
||||
public void add() throws IOException {
|
||||
execute("add", ".");
|
||||
execute(true, "add", ".");
|
||||
}
|
||||
|
||||
public void commit(@Nullable String commitMessage) throws IOException {
|
||||
if (commitMessage == null) {
|
||||
commitMessage = "Sample commit message";
|
||||
}
|
||||
execute("commit", "-m", commitMessage);
|
||||
execute(true, "commit", "-m", commitMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit with a sample commit message. Use this when commit message doesn't matter to your test.
|
||||
*/
|
||||
public void commit() throws IOException {
|
||||
commit(null);
|
||||
}
|
||||
|
||||
public void config(String... parameters) throws IOException {
|
||||
String[] pars = new String[parameters.length+1];
|
||||
pars[0] = "config";
|
||||
System.arraycopy(parameters, 0, pars, 1, parameters.length);
|
||||
execute(pars);
|
||||
execute(true, pars);
|
||||
}
|
||||
|
||||
public ProcessOutput log(String... parameters) throws IOException {
|
||||
String[] pars = new String[parameters.length+1];
|
||||
pars[0] = "log";
|
||||
System.arraycopy(parameters, 0, pars, 1, parameters.length);
|
||||
return execute(pars);
|
||||
return execute(false, pars);
|
||||
}
|
||||
|
||||
public void merge() throws IOException {
|
||||
execute("merge");
|
||||
execute(true, "merge");
|
||||
}
|
||||
|
||||
public void mv(VirtualFile file, String newPath) throws IOException {
|
||||
execute("mv", file.getPath(), newPath);
|
||||
execute(true, "mv", file.getPath(), newPath);
|
||||
}
|
||||
|
||||
public void pull() throws IOException {
|
||||
execute("pull");
|
||||
execute(true, "pull");
|
||||
}
|
||||
|
||||
public void push() throws IOException {
|
||||
execute("push");
|
||||
execute(true, "push");
|
||||
}
|
||||
|
||||
public void update() throws IOException {
|
||||
execute("update");
|
||||
execute(true, "update");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+6
-4
@@ -37,6 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ControlFlowBuilder
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.MaybeReturnInstruction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"OverlyComplexClass"})
|
||||
@@ -442,17 +443,18 @@ public class ControlFlowUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<GrStatement> collectReturns(PsiElement element) {
|
||||
public static List<GrStatement> collectReturns(@Nullable PsiElement element) {
|
||||
return collectReturns(element, element instanceof GrCodeBlock);
|
||||
}
|
||||
public static List<GrStatement> collectReturns(PsiElement element, final boolean allExitPoints) {
|
||||
public static List<GrStatement> collectReturns(@Nullable PsiElement element, final boolean allExitPoints) {
|
||||
if (element == null) return Collections.emptyList();
|
||||
|
||||
final Instruction[] flow;
|
||||
if (element instanceof GrCodeBlock) {
|
||||
flow = ((GrCodeBlock)element).getControlFlow();
|
||||
}
|
||||
else {
|
||||
flow = new ControlFlowBuilder(element.getProject()).buildControlFlow(
|
||||
(GroovyPsiElement)element, null, null);
|
||||
flow = new ControlFlowBuilder(element.getProject()).buildControlFlow((GroovyPsiElement)element, null, null);
|
||||
}
|
||||
boolean[] visited = new boolean[flow.length];
|
||||
final List<GrStatement> res = new ArrayList<GrStatement>();
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.jetbrains.plugins.groovy.dsl;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import groovy.lang.Closure;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -25,10 +26,9 @@ public class CustomMembersGenerator implements GdslMembersHolderConsumer {
|
||||
private final GroovyClassDescriptor myDescriptor;
|
||||
private final String myQualifiedName;
|
||||
|
||||
public CustomMembersGenerator(GroovyClassDescriptor descriptor) {
|
||||
public CustomMembersGenerator(GroovyClassDescriptor descriptor, PsiType type) {
|
||||
myDescriptor = descriptor;
|
||||
myProject = descriptor.getProject();
|
||||
final PsiType type = descriptor.getPsiType();
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
if (psiClass != null) {
|
||||
@@ -72,9 +72,13 @@ public class CustomMembersGenerator implements GdslMembersHolderConsumer {
|
||||
|
||||
@Nullable
|
||||
public CustomMembersHolder getMembersHolder() {
|
||||
// Add non-code members holder
|
||||
if (!myMethods.isEmpty()) {
|
||||
addMemberHolder(NonCodeMembersHolder.generateMembers(myMethods, myDescriptor.getPlaceFile()));
|
||||
addMemberHolder(new CustomMembersHolder() {
|
||||
@Override
|
||||
public boolean processMembers(GroovyClassDescriptor descriptor, PsiScopeProcessor processor, ResolveState state) {
|
||||
return NonCodeMembersHolder.generateMembers(myMethods, descriptor.getPlaceFile()).processMembers(descriptor, processor, state);
|
||||
}
|
||||
});
|
||||
}
|
||||
return myDepot;
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
package org.jetbrains.plugins.groovy.dsl;
|
||||
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.plugins.groovy.dsl.dsltop.GdslMembersProvider
|
||||
|
||||
/**
|
||||
@@ -10,8 +9,8 @@ import org.jetbrains.plugins.groovy.dsl.dsltop.GdslMembersProvider
|
||||
*/
|
||||
public class ExtensibleCustomMembersGenerator extends CustomMembersGenerator {
|
||||
|
||||
public ExtensibleCustomMembersGenerator(GroovyClassDescriptor descriptor) {
|
||||
super(descriptor)
|
||||
public ExtensibleCustomMembersGenerator(GroovyClassDescriptor descriptor, PsiType type) {
|
||||
super(descriptor, type)
|
||||
}
|
||||
|
||||
def methodMissing(String name, args) {
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.jetbrains.plugins.groovy.dsl;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.containers.ConcurrentHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.dsl.holders.CustomMembersHolder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class FactorTree {
|
||||
private static final Object ourHolderKey = new Object();
|
||||
private final Map myCache = new ConcurrentHashMap();
|
||||
|
||||
public void cache(GroovyClassDescriptor descriptor, CustomMembersHolder holder) {
|
||||
Map current = myCache;
|
||||
for (Factor factor : descriptor.affectingFactors) {
|
||||
Object key;
|
||||
switch (factor) {
|
||||
case placeElement: key = descriptor.getPlace(); break;
|
||||
//case placeFile: key = descriptor.getPlaceFile(); break;
|
||||
case qualifierType: key = descriptor.getPsiType().getCanonicalText(); break;
|
||||
default: throw new IllegalStateException("Unknown variant: "+ factor);
|
||||
}
|
||||
Map next = (Map)current.get(key);
|
||||
if (next == null) current.put(key, next = new ConcurrentHashMap());
|
||||
current = next;
|
||||
}
|
||||
|
||||
current.put(ourHolderKey, holder);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CustomMembersHolder retrieve(PsiElement place, String qualifierType) {
|
||||
return retrieveImpl(place, qualifierType, myCache);
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CustomMembersHolder retrieveImpl(@NotNull PsiElement place,
|
||||
@NotNull String qualifierType, @Nullable Map current) {
|
||||
if (current == null) return null;
|
||||
|
||||
CustomMembersHolder result;
|
||||
|
||||
result = (CustomMembersHolder)current.get(ourHolderKey);
|
||||
if (result != null) return result;
|
||||
|
||||
result = retrieveImpl(place, qualifierType, (Map)current.get(qualifierType));
|
||||
if (result != null) return result;
|
||||
|
||||
/*
|
||||
result = retrieveImpl(place, placeFile, qualifierType, (Map)current.get(placeFile));
|
||||
if (result != null) return result;
|
||||
|
||||
*/
|
||||
return retrieveImpl(place, qualifierType, (Map)current.get(place));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum Factor {
|
||||
qualifierType, placeElement//, placeFile
|
||||
}
|
||||
@@ -26,6 +26,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@@ -44,13 +46,13 @@ public class GroovyClassDescriptor {
|
||||
private final PsiType myPsiType;
|
||||
private final PsiElement myPlace;
|
||||
private final PsiFile myFile;
|
||||
private final boolean myPlaceDependent;
|
||||
private boolean myPlaceElementAccessed;
|
||||
|
||||
public GroovyClassDescriptor(@NotNull PsiType psiType, GroovyPsiElement place, boolean placeDependent, final PsiFile placeFile) {
|
||||
@SuppressWarnings({"SetReplaceableByEnumSet"}) //order is important
|
||||
final Set<Factor> affectingFactors = new LinkedHashSet<Factor>();
|
||||
|
||||
public GroovyClassDescriptor(@NotNull PsiType psiType, GroovyPsiElement place, final PsiFile placeFile) {
|
||||
myPsiType = psiType;
|
||||
myPlace = place;
|
||||
myPlaceDependent = placeDependent;
|
||||
myFile = placeFile;
|
||||
}
|
||||
|
||||
@@ -59,58 +61,32 @@ public class GroovyClassDescriptor {
|
||||
}
|
||||
|
||||
public GlobalSearchScope getResolveScope() {
|
||||
//affectingFactors.add(Factor.placeFile);
|
||||
return myPlace.getResolveScope();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTypeText() {
|
||||
return myPsiType.getCanonicalText();
|
||||
return getPsiType().getCanonicalText();
|
||||
}
|
||||
|
||||
public boolean isInheritor(String qname) {
|
||||
return InheritanceUtil.isInheritor(myPsiType, qname);
|
||||
return InheritanceUtil.isInheritor(getPsiType(), qname);
|
||||
}
|
||||
|
||||
public PsiElement getPlace() {
|
||||
myPlaceElementAccessed = true;
|
||||
affectingFactors.add(Factor.placeElement);
|
||||
return myPlace;
|
||||
}
|
||||
|
||||
public PsiType getPsiType() {
|
||||
affectingFactors.add(Factor.qualifierType);
|
||||
return myPsiType;
|
||||
}
|
||||
|
||||
public PsiFile getPlaceFile() {
|
||||
//affectingFactors.add(Factor.placeFile);
|
||||
return myFile;
|
||||
}
|
||||
|
||||
public boolean placeAccessed() {
|
||||
return myPlaceElementAccessed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
GroovyClassDescriptor that = (GroovyClassDescriptor)o;
|
||||
|
||||
if (!myPsiType.isValid() || !that.myPsiType.isValid()) return false;
|
||||
if (!myPsiType.equals(that.myPsiType)) return false;
|
||||
|
||||
if (myPlaceDependent) {
|
||||
return myPlace.equals(that.myPlace);
|
||||
}
|
||||
|
||||
return myFile.equals(that.myFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myPsiType.hashCode() * 31 + myFile.hashCode();
|
||||
if (myPlaceDependent) {
|
||||
return result * 31 + myPlace.hashCode();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,6 @@ import org.jetbrains.plugins.groovy.dsl.toplevel.ClassContextFilter;
|
||||
import org.jetbrains.plugins.groovy.dsl.toplevel.ContextFilter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -35,18 +31,16 @@ public class GroovyDslScript {
|
||||
public final Project project;
|
||||
public final VirtualFile file;
|
||||
public final GroovyDslExecutor executor;
|
||||
private final CachedValue<Pair<ConcurrentMap<String, Boolean>, ConcurrentMap<GroovyClassDescriptor, CustomMembersHolder>>> myMaps;
|
||||
private final CachedValue<FactorTree> myMaps;
|
||||
|
||||
public GroovyDslScript(final Project project, VirtualFile file, GroovyDslExecutor executor) {
|
||||
this.project = project;
|
||||
this.file = file;
|
||||
this.executor = executor;
|
||||
myMaps = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Pair<ConcurrentMap<String, Boolean>, ConcurrentMap<GroovyClassDescriptor, CustomMembersHolder>>>() {
|
||||
myMaps = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<FactorTree>() {
|
||||
@Override
|
||||
public Result<Pair<ConcurrentMap<String, Boolean>, ConcurrentMap<GroovyClassDescriptor, CustomMembersHolder>>> compute() {
|
||||
ConcurrentMap<String, Boolean> specificities = new ConcurrentHashMap<String, Boolean>();
|
||||
ConcurrentMap<GroovyClassDescriptor, CustomMembersHolder> holders = new ConcurrentHashMap<GroovyClassDescriptor, CustomMembersHolder>();
|
||||
return Result.create(Pair.create(specificities, holders), PsiModificationTracker.MODIFICATION_COUNT, ProjectRootManager.getInstance(project));
|
||||
public Result<FactorTree> compute() {
|
||||
return Result.create(new FactorTree(), PsiModificationTracker.MODIFICATION_COUNT, ProjectRootManager.getInstance(project));
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
@@ -57,41 +51,26 @@ public class GroovyDslScript {
|
||||
final GroovyPsiElement place,
|
||||
final PsiFile placeFile,
|
||||
final String qname) {
|
||||
final Pair<ConcurrentMap<String, Boolean>, ConcurrentMap<GroovyClassDescriptor, CustomMembersHolder>> maps = myMaps.getValue();
|
||||
Map<String, Boolean> specificities = maps.first;
|
||||
boolean firstTime = !specificities.containsKey(qname);
|
||||
|
||||
final boolean placeDependent = firstTime || specificities.get(qname);
|
||||
GroovyClassDescriptor descriptor = new GroovyClassDescriptor(psiType, place, placeDependent, placeFile);
|
||||
|
||||
final ConcurrentMap<GroovyClassDescriptor, CustomMembersHolder> members = maps.second;
|
||||
CustomMembersHolder holder = members.get(descriptor);
|
||||
final FactorTree cache = myMaps.getValue();
|
||||
CustomMembersHolder holder = cache.retrieve(place, qname);
|
||||
GroovyClassDescriptor descriptor = new GroovyClassDescriptor(psiType, place, placeFile);
|
||||
if (holder == null) {
|
||||
holder = addGdslMembers(descriptor, qname);
|
||||
|
||||
if (firstTime) {
|
||||
final boolean placeAccessed = descriptor.placeAccessed();
|
||||
specificities.put(qname, placeAccessed);
|
||||
final GroovyClassDescriptor newDescriptor = new GroovyClassDescriptor(psiType, place, placeAccessed, placeFile);
|
||||
members.putIfAbsent(newDescriptor, holder);
|
||||
}
|
||||
else {
|
||||
members.putIfAbsent(descriptor, holder);
|
||||
}
|
||||
holder = addGdslMembers(descriptor, qname, psiType);
|
||||
cache.cache(descriptor, holder);
|
||||
}
|
||||
|
||||
return holder.processMembers(descriptor, processor, ResolveState.initial());
|
||||
}
|
||||
|
||||
private CustomMembersHolder addGdslMembers(GroovyClassDescriptor descriptor, String qname) {
|
||||
private CustomMembersHolder addGdslMembers(GroovyClassDescriptor descriptor, String qname, final PsiType psiType) {
|
||||
final ProcessingContext ctx = new ProcessingContext();
|
||||
ctx.put(ClassContextFilter.getClassKey(qname), descriptor.getPsiType());
|
||||
ctx.put(ClassContextFilter.getClassKey(qname), psiType);
|
||||
try {
|
||||
if (!isApplicable(executor, descriptor, ctx)) {
|
||||
return CustomMembersHolder.EMPTY;
|
||||
}
|
||||
|
||||
final ExtensibleCustomMembersGenerator generator = new ExtensibleCustomMembersGenerator(descriptor);
|
||||
final ExtensibleCustomMembersGenerator generator = new ExtensibleCustomMembersGenerator(descriptor, psiType);
|
||||
executor.processVariants(descriptor, generator, ctx);
|
||||
return generator.getMembersHolder();
|
||||
}
|
||||
|
||||
-74
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.dsl.toplevel;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
*/
|
||||
public class CategoryMethodProvider {
|
||||
private static final Key<CachedValue<MultiMap<String, PsiMethod>>> METHOD_KEY = Key.create("Category methods");
|
||||
|
||||
private CategoryMethodProvider() {
|
||||
}
|
||||
|
||||
public static List<PsiMethod> provideMethods(@NotNull PsiType psiType,
|
||||
final Project project,
|
||||
String className,
|
||||
final GlobalSearchScope scope,
|
||||
final Function<PsiMethod, PsiMethod> converter) {
|
||||
final PsiClass categoryClass = JavaPsiFacade.getInstance(project).findClass(className, scope);
|
||||
if (categoryClass == null) return Collections.emptyList();
|
||||
final MultiMap<String, PsiMethod> map = CachedValuesManager.getManager(project)
|
||||
.getCachedValue(categoryClass, METHOD_KEY, new CachedValueProvider<MultiMap<String, PsiMethod>>() {
|
||||
@Override
|
||||
public Result<MultiMap<String, PsiMethod>> compute() {
|
||||
MultiMap<String, PsiMethod> map = new MultiMap<String, PsiMethod>();
|
||||
PsiManager manager = PsiManager.getInstance(project);
|
||||
for (PsiMethod m : categoryClass.getMethods()) {
|
||||
final PsiParameter[] params = m.getParameterList().getParameters();
|
||||
if (params.length == 0) continue;
|
||||
final PsiType parameterType = TypesUtil.boxPrimitiveType(params[0].getType(), manager, scope);
|
||||
PsiType targetType = TypeConversionUtil.erasure(parameterType);
|
||||
map.putValue(targetType.getCanonicalText(), converter.fun(m));
|
||||
}
|
||||
return Result.create(map, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, ProjectRootManager.getInstance(project));
|
||||
}
|
||||
}, false);
|
||||
Set<String> superTypes = ResolveUtil.getAllSuperTypes(psiType, project).keySet();
|
||||
List<PsiMethod> result = new ArrayList<PsiMethod>();
|
||||
for (String superType : superTypes) {
|
||||
result.addAll(map.get(superType));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+20
-5
@@ -24,11 +24,12 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.changeSignature.JavaThrownExceptionInfo;
|
||||
import com.intellij.refactoring.changeSignature.ThrownExceptionInfo;
|
||||
import com.intellij.ui.components.JBList;
|
||||
@@ -64,6 +65,7 @@ import java.util.*;
|
||||
*/
|
||||
public class CreateParameterForFieldIntention extends Intention {
|
||||
private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.intentions.control.CreateParameterForFieldIntention");
|
||||
private static final Key<CachedValue<List<GrField>>> FIELD_CANDIDATES = Key.create("Fields.candidates");
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -125,7 +127,6 @@ public class CreateParameterForFieldIntention extends Intention {
|
||||
}, GroovyIntentionsBundle.message("create.parameter.for.field.intention.name"), null);
|
||||
}
|
||||
}).createPopup().showInBestPositionFor(editor);
|
||||
|
||||
}
|
||||
|
||||
private static void performForConstructor(PsiElement element, final Project project, Editor editor, List<GrField> candidates) {
|
||||
@@ -243,12 +244,11 @@ public class CreateParameterForFieldIntention extends Intention {
|
||||
final PsiClass clazz = constructor.getContainingClass();
|
||||
|
||||
if (!(clazz instanceof GrTypeDefinition)) return null;
|
||||
return findCandidates(constructor, (GrTypeDefinition)clazz);
|
||||
return findCandidatesCached(constructor, (GrTypeDefinition)clazz);
|
||||
}
|
||||
|
||||
private static List<GrField> findCandidates(GrMethod constructor, final GrTypeDefinition clazz) {
|
||||
final List<GrField> usedFields = new ArrayList<GrField>();
|
||||
//ContainerUtil.addAll(fields, clazz.getFields());
|
||||
final GrOpenBlock block = constructor.getBlock();
|
||||
LOG.assertTrue(block != null);
|
||||
|
||||
@@ -290,6 +290,21 @@ public class CreateParameterForFieldIntention extends Intention {
|
||||
return fields;
|
||||
}
|
||||
|
||||
private static List<GrField> findCandidatesCached(final GrMethod constructor, final GrTypeDefinition clazz) {
|
||||
final CachedValue<List<GrField>> value = constructor.getUserData(FIELD_CANDIDATES);
|
||||
if (value != null && value.getValue() != null) return value.getValue();
|
||||
final CachedValue<List<GrField>> cachedValue =
|
||||
CachedValuesManager.getManager(constructor.getProject()).createCachedValue(new CachedValueProvider<List<GrField>>() {
|
||||
@Override
|
||||
public Result<List<GrField>> compute() {
|
||||
return Result.create(findCandidates(constructor, clazz), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
|
||||
}
|
||||
}, false);
|
||||
constructor.putUserData(FIELD_CANDIDATES, cachedValue);
|
||||
return cachedValue.getValue();
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static List<GrMethod> findConstructorCandidates(PsiElement element) {
|
||||
final GrField field = PsiTreeUtil.getParentOfType(element, GrField.class);
|
||||
@@ -302,7 +317,7 @@ public class CreateParameterForFieldIntention extends Intention {
|
||||
final PsiMethod[] constructors = psiClass.getConstructors();
|
||||
final PsiManager manager = field.getManager();
|
||||
for (PsiMethod constructor : constructors) {
|
||||
final List<GrField> fields = findCandidates(((GrMethod)constructor), psiClass);
|
||||
final List<GrField> fields = findCandidatesCached(((GrMethod)constructor), psiClass);
|
||||
if (ContainerUtil.find(fields, new Condition<GrField>() {
|
||||
@Override
|
||||
public boolean value(GrField grField) {
|
||||
|
||||
+56
-7
@@ -15,16 +15,22 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.resolve;
|
||||
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.VolatileNotNullLazyValue;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.dsl.GdslMembersHolderConsumer;
|
||||
import org.jetbrains.plugins.groovy.dsl.GroovyClassDescriptor;
|
||||
import org.jetbrains.plugins.groovy.dsl.dsltop.GdslMembersProvider;
|
||||
import org.jetbrains.plugins.groovy.dsl.holders.CustomMembersHolder;
|
||||
import org.jetbrains.plugins.groovy.dsl.toplevel.CategoryMethodProvider;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
|
||||
|
||||
/**
|
||||
@@ -32,6 +38,8 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
|
||||
*/
|
||||
@SuppressWarnings({"MethodMayBeStatic"})
|
||||
public class GdkMethodDslProvider implements GdslMembersProvider {
|
||||
private static final Key<CachedValue<MultiMap<String, PsiMethod>>> METHOD_KEY = Key.create("Category methods");
|
||||
|
||||
public void category(String className, GdslMembersHolderConsumer consumer) {
|
||||
processCategoryMethods(className, consumer, new Function<PsiMethod, PsiMethod>() {
|
||||
public PsiMethod fun(PsiMethod m) {
|
||||
@@ -53,19 +61,60 @@ public class GdkMethodDslProvider implements GdslMembersProvider {
|
||||
}
|
||||
|
||||
public static void processCategoryMethods(final String className, final GdslMembersHolderConsumer consumer, final Function<PsiMethod, PsiMethod> converter) {
|
||||
final GlobalSearchScope scope = consumer.getResolveScope();
|
||||
final PsiClass categoryClass = JavaPsiFacade.getInstance(consumer.getProject()).findClass(className, scope);
|
||||
if (categoryClass == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final VolatileNotNullLazyValue<MultiMap<String, PsiMethod>> methodsMap = new VolatileNotNullLazyValue<MultiMap<String, PsiMethod>>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected MultiMap<String, PsiMethod> compute() {
|
||||
return retrieveMethodMap(consumer.getProject(), scope, converter, categoryClass);
|
||||
}
|
||||
};
|
||||
|
||||
consumer.addMemberHolder(new CustomMembersHolder() {
|
||||
|
||||
@Override
|
||||
public boolean processMembers(GroovyClassDescriptor descriptor, PsiScopeProcessor processor, ResolveState state) {
|
||||
final PsiType psiType = descriptor.getPsiType();
|
||||
if (psiType == null) return true;
|
||||
|
||||
for (PsiMethod method : CategoryMethodProvider.provideMethods(psiType, descriptor.getProject(), className, descriptor.getResolveScope(), converter)) {
|
||||
if (!processor.execute(method, state)) {
|
||||
return false;
|
||||
final MultiMap<String, PsiMethod> map = methodsMap.getValue();
|
||||
for (String superType : ResolveUtil.getAllSuperTypes(psiType, descriptor.getProject()).keySet()) {
|
||||
for (PsiMethod method : map.get(superType)) {
|
||||
if (!processor.execute(method, state)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static MultiMap<String, PsiMethod> retrieveMethodMap(final Project project,
|
||||
final GlobalSearchScope scope,
|
||||
final Function<PsiMethod, PsiMethod> converter,
|
||||
@NotNull final PsiClass categoryClass) {
|
||||
return CachedValuesManager.getManager(project)
|
||||
.getCachedValue(categoryClass, METHOD_KEY, new CachedValueProvider<MultiMap<String, PsiMethod>>() {
|
||||
@Override
|
||||
public Result<MultiMap<String, PsiMethod>> compute() {
|
||||
MultiMap<String, PsiMethod> map = new MultiMap<String, PsiMethod>();
|
||||
PsiManager manager = PsiManager.getInstance(project);
|
||||
for (PsiMethod m : categoryClass.getMethods()) {
|
||||
final PsiParameter[] params = m.getParameterList().getParameters();
|
||||
if (params.length == 0) continue;
|
||||
final PsiType parameterType = TypesUtil.boxPrimitiveType(params[0].getType(), manager, scope);
|
||||
PsiType targetType = TypeConversionUtil.erasure(parameterType);
|
||||
map.putValue(targetType.getCanonicalText(), converter.fun(m));
|
||||
}
|
||||
return Result.create(map, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT, ProjectRootManager.getInstance(project));
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
|
||||
+30
-32
@@ -80,38 +80,42 @@ public class GroovyInlineMethodUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
PsiReference reference = editor != null ? TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()) : null;
|
||||
if (!invokedOnReference || reference == null) {
|
||||
String message = GroovyRefactoringBundle.message("multiple.method.inline.is.not.suppored", REFACTORING_NAME);
|
||||
showErrorMessage(message, project, editor);
|
||||
return null;
|
||||
}
|
||||
if (invokedOnReference) {
|
||||
PsiReference reference = editor != null ? TargetElementUtil.findReference(editor, editor.getCaretModel().getOffset()) : null;
|
||||
if (reference == null) return null;
|
||||
|
||||
PsiElement element = reference.getElement();
|
||||
PsiElement element = reference.getElement();
|
||||
|
||||
if (element.getContainingFile() instanceof GroovyFile) {
|
||||
if (!(isStaticMethod(method) || areInSameClass(element, method))) { // todo implement for other cases
|
||||
if (element.getContainingFile() instanceof GroovyFile) {
|
||||
if (!(isStaticMethod(method) || areInSameClass(element, method))) { // todo implement for other cases
|
||||
// showErrorMessage("Other class support will be implemented soon", myProject);
|
||||
// return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(element instanceof GrExpression && element.getParent() instanceof GrCallExpression)) {
|
||||
String message = GroovyRefactoringBundle.message("refactoring.is.available.only.for.method.calls", REFACTORING_NAME);
|
||||
showErrorMessage(message, project, editor);
|
||||
return null;
|
||||
}
|
||||
|
||||
GrCallExpression call = (GrCallExpression)element.getParent();
|
||||
|
||||
if (PsiTreeUtil.getParentOfType(element, GrParameter.class) != null) {
|
||||
String message = GroovyRefactoringBundle.message("refactoring.is.not.supported.in.parameter.initializers", REFACTORING_NAME);
|
||||
showErrorMessage(message, project, editor);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
GroovyRefactoringUtil.highlightOccurrences(project, editor, new GrExpression[]{call});
|
||||
if (hasBadReturns(method) && !isTailMethodCall(call)) {
|
||||
String message = GroovyRefactoringBundle
|
||||
.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow", REFACTORING_NAME);
|
||||
showErrorMessage(message, project, editor);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(element instanceof GrExpression && element.getParent() instanceof GrCallExpression)) {
|
||||
String message = GroovyRefactoringBundle.message("refactoring.is.available.only.for.method.calls", REFACTORING_NAME);
|
||||
showErrorMessage(message, project, editor);
|
||||
return null;
|
||||
}
|
||||
|
||||
GrCallExpression call = (GrCallExpression) element.getParent();
|
||||
|
||||
if (PsiTreeUtil.getParentOfType(element, GrParameter.class) != null) {
|
||||
String message = GroovyRefactoringBundle.message("refactoring.is.not.supported.in.parameter.initializers", REFACTORING_NAME);
|
||||
showErrorMessage(message, project, editor);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
GroovyRefactoringUtil.highlightOccurrences(project, editor, new GrExpression[]{call});
|
||||
if (method.getBlock() == null) {
|
||||
String message;
|
||||
if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
@@ -123,12 +127,6 @@ public class GroovyInlineMethodUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (hasBadReturns(method) && !isTailMethodCall(call)) {
|
||||
String message = GroovyRefactoringBundle.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow", REFACTORING_NAME);
|
||||
showErrorMessage(message, project, editor);
|
||||
return null;
|
||||
}
|
||||
|
||||
return inlineMethodDialogResult(method, project, invokedOnReference);
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -48,11 +48,15 @@ class GroovyTransformationsTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
public void testVetoableTransform() throws Throwable { doPlainTest() }
|
||||
|
||||
public void testNewifyTransform1() throws Throwable { doVariantsTest('newInstance', 'new', 'new', 'new',
|
||||
public void testNewifyTransform1() throws Throwable { doVariantsTest('newInstance', 'new', 'new',
|
||||
'newInstance', 'newInstance0', 'newInstanceCallerCache', 'next') }
|
||||
|
||||
public void testNewifyTransform2() throws Throwable { doVariantsTest('Leaf', 'Leaf', 'Leaf') }
|
||||
|
||||
public void testNewifyTransform3() throws Throwable { doVariantsTest('Bazz', 'Bazz') }
|
||||
|
||||
@Newify rubyLikeNew() {
|
||||
assert Integer.ne == 42
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user