Merge branch 'master' of git@git.labs.intellij.net:idea/community

This commit is contained in:
Eugene Kudelevsky
2010-04-22 20:50:43 +04:00
99 changed files with 1698 additions and 500 deletions
@@ -51,7 +51,7 @@ public class JavaCompletionStatistician extends CompletionStatistician{
}
}
LookupItem item = element.as(LookupItem.class);
LookupItem item = LookupItem.from(element);
if (item == null) return null;
PsiType qualifierType = JavaCompletionUtil.getQualifierType(item);
@@ -789,9 +789,8 @@ public class JavaCompletionUtil {
return typed.getType();
}
final PsiType qualifierType = getPsiType(element.getObject());
final LookupItem lookupItem = element.as(LookupItem.class);
final LookupItem lookupItem = LookupItem.from(element);
if (lookupItem != null) {
final Object o = lookupItem.getAttribute(LookupItem.TYPE);
if (o instanceof PsiType) {
@@ -31,6 +31,10 @@ public class StaticMembersWeigher extends CompletionWeigher {
final PsiElement position = loc.getCompletionParameters().getPosition();
if (!position.isValid()) return 0;
// cheap weigher applicability goes first
final Object o = element.getObject();
if (!(o instanceof PsiMember)) return 0;
if (PsiTreeUtil.getParentOfType(position, PsiDocComment.class) != null) return 0;
if (position.getParent() instanceof PsiReferenceExpression) {
final PsiReferenceExpression refExpr = (PsiReferenceExpression)position.getParent();
@@ -43,9 +47,6 @@ public class StaticMembersWeigher extends CompletionWeigher {
}
}
final Object o = element.getObject();
if (!(o instanceof PsiMember)) return 0;
if (((PsiMember)o).hasModifierProperty(PsiModifier.STATIC)) {
if (o instanceof PsiMethod) return 5;
if (o instanceof PsiField) return 4;
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.ExternalAnnotationsManager;
import com.intellij.codeInsight.documentation.DocumentationManager;
import com.intellij.lang.ASTNode;
import com.intellij.lang.LangBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -28,6 +29,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
import com.intellij.psi.impl.source.tree.JavaDocElementType;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.javadoc.PsiDocTagValue;
@@ -315,10 +317,7 @@ public class JavaDocInfoGenerator {
PsiDocComment comment = getDocComment(aClass);
if (comment != null) {
generateDescription(buffer, comment);
generateDeprecatedSection(buffer, comment);
generateSinceSection(buffer, comment);
generateSeeAlsoSection(buffer, comment);
generateCommonSection(buffer, comment);
generateTypeParametersSection(buffer, aClass);
}
generateEpilogue(buffer);
@@ -418,10 +417,7 @@ public class JavaDocInfoGenerator {
PsiDocComment comment = getDocComment(field);
if (comment != null) {
generateDescription(buffer, comment);
generateDeprecatedSection(buffer, comment);
generateSinceSection(buffer, comment);
generateSeeAlsoSection(buffer, comment);
generateCommonSection(buffer, comment);
}
generateEpilogue(buffer);
@@ -463,6 +459,23 @@ public class JavaDocInfoGenerator {
private void generatePackageJavaDoc(final StringBuilder buffer, final PsiPackage psiPackage) {
for(PsiDirectory directory: psiPackage.getDirectories()) {
final PsiFile packageInfoFile = directory.findFile("package-info.java");
if (packageInfoFile != null) {
final ASTNode node = packageInfoFile.getNode();
if (node != null) {
final ASTNode docCommentNode = node.findChildByType(JavaDocElementType.DOC_COMMENT);
if (docCommentNode != null) {
final PsiDocComment docComment = (PsiDocComment)docCommentNode.getPsi();
generatePrologue(buffer);
generateCommonSection(buffer, docComment);
generateEpilogue(buffer);
break;
}
}
}
PsiFile packageHtmlFile = directory.findFile("package.html");
if (packageHtmlFile != null) {
generatePackageHtmlJavaDoc(buffer, packageHtmlFile);
@@ -471,6 +484,13 @@ public class JavaDocInfoGenerator {
}
}
private void generateCommonSection(StringBuilder buffer, PsiDocComment docComment) {
generateDescription(buffer, docComment);
generateDeprecatedSection(buffer, docComment);
generateSinceSection(buffer, docComment);
generateSeeAlsoSection(buffer, docComment);
}
private void generatePackageHtmlJavaDoc(final StringBuilder buffer, final PsiFile packageHtmlFile) {
String htmlText;
XmlFile packageXmlFile = (XmlFile) packageHtmlFile;
@@ -502,9 +522,7 @@ public class JavaDocInfoGenerator {
generatePrologue(buffer);
generateDescription(buffer, docComment);
generateSinceSection(buffer, docComment);
generateSeeAlsoSection(buffer, docComment);
generateCommonSection(buffer, docComment);
generateEpilogue(buffer);
}
@@ -40,15 +40,17 @@ public class WrongPackageStatementInspection extends BaseJavaLocalInspectionTool
if (file instanceof PsiJavaFile) {
if (JspPsiUtil.isInJspFile(file)) return null;
PsiJavaFile javaFile = (PsiJavaFile)file;
// highlight the first class in the file only
PsiClass[] classes = javaFile.getClasses();
if (classes.length == 0) return null;
PsiDirectory directory = javaFile.getContainingDirectory();
if (directory == null) return null;
PsiPackage dirPackage = JavaDirectoryService.getInstance().getPackage(directory);
if (dirPackage == null) return null;
PsiPackageStatement packageStatement = javaFile.getPackageStatement();
// highlight the first class in the file only
PsiClass[] classes = javaFile.getClasses();
if (classes.length == 0 && packageStatement == null) return null;
String packageName = dirPackage.getQualifiedName();
if (!Comparing.strEqual(packageName, "", true) && packageStatement == null) {
String description = JavaErrorMessages.message("missing.package.statement", packageName);
@@ -75,7 +77,7 @@ public class WrongPackageStatementInspection extends BaseJavaLocalInspectionTool
String description = JavaErrorMessages.message("package.name.file.path.mismatch",
packageReference.getText(),
dirPackage.getQualifiedName());
return new ProblemDescriptor[]{manager.createProblemDescriptor(packageStatement, description, isOnTheFly, availableFixes.toArray(new LocalQuickFix[availableFixes.size()]), ProblemHighlightType.GENERIC_ERROR_OR_WARNING)};
return new ProblemDescriptor[]{manager.createProblemDescriptor(packageStatement.getPackageReference(), description, isOnTheFly, availableFixes.toArray(new LocalQuickFix[availableFixes.size()]), ProblemHighlightType.GENERIC_ERROR_OR_WARNING)};
}
}
@@ -24,6 +24,8 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.formatter.common.AbstractBlock;
import com.intellij.psi.formatter.common.JavaBlockUtil;
import com.intellij.psi.formatter.java.wrap.JavaWrapManager;
import com.intellij.psi.formatter.java.wrap.ReservedWrapsProvider;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.impl.source.tree.java.ClassElement;
@@ -37,7 +39,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlock {
public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlock, ReservedWrapsProvider {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.formatter.java.AbstractJavaBlock");
protected final CodeStyleSettings mySettings;
@@ -51,16 +53,21 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
protected Alignment myReservedAlignment;
protected Alignment myReservedAlignment2;
private final JavaWrapManager myWrapManager;
protected AbstractJavaBlock(final ASTNode node,
final Wrap wrap,
final Alignment alignment,
final Indent indent,
final CodeStyleSettings settings) {
protected AbstractJavaBlock(final ASTNode node, final Wrap wrap, final Alignment alignment, final Indent indent,
final CodeStyleSettings settings)
{
this(node, wrap, alignment, indent, settings, JavaWrapManager.INSTANCE);
}
protected AbstractJavaBlock(final ASTNode node, final Wrap wrap, final Alignment alignment, final Indent indent,
final CodeStyleSettings settings, JavaWrapManager wrapManager)
{
super(node, wrap, alignment);
mySettings = settings;
myIndent = indent;
myWrapManager = wrapManager;
}
public static Block createJavaBlock(final ASTNode child,
@@ -159,7 +166,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
}
final ASTNode prevElement = getPrevElement(child);
final ASTNode prevElement = FormattingAstUtil.getPrevElement(child);
if (prevElement != null && prevElement.getElementType() == JavaElementType.MODIFIER_LIST) {
return Indent.getNoneIndent();
}
@@ -234,51 +241,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
@Nullable
protected Wrap createChildWrap() {
final IElementType nodeType = myNode.getElementType();
if (nodeType == JavaElementType.EXTENDS_LIST || nodeType == JavaElementType.IMPLEMENTS_LIST) {
return Wrap.createWrap(getWrapType(mySettings.EXTENDS_LIST_WRAP), false);
}
else if (nodeType == JavaElementType.BINARY_EXPRESSION) {
Wrap actualWrap = myWrap != null ? myWrap : getReservedWrap(JavaElementType.BINARY_EXPRESSION);
if (actualWrap == null) {
return Wrap.createWrap(getWrapType(mySettings.BINARY_OPERATION_WRAP), false);
}
else {
if (!hasTheSamePriority(myNode.getTreeParent())) {
return Wrap.createChildWrap(actualWrap, getWrapType(mySettings.BINARY_OPERATION_WRAP), false);
}
else {
return actualWrap;
}
}
}
else if (nodeType == JavaElementType.CONDITIONAL_EXPRESSION) {
return Wrap.createWrap(getWrapType(mySettings.TERNARY_OPERATION_WRAP), false);
}
else if (nodeType == JavaElementType.ASSERT_STATEMENT) {
return Wrap.createWrap(getWrapType(mySettings.ASSERT_STATEMENT_WRAP), false);
}
else if (nodeType == JavaElementType.FOR_STATEMENT) {
return Wrap.createWrap(getWrapType(mySettings.FOR_STATEMENT_WRAP), false);
}
else if (nodeType == JavaElementType.THROWS_LIST) {
return Wrap.createWrap(getWrapType(mySettings.THROWS_LIST_WRAP), true);
}
else if (nodeType == JavaElementType.CODE_BLOCK) {
return Wrap.createWrap(Wrap.NORMAL, false);
}
else if (isAssignment()) {
return Wrap.createWrap(getWrapType(mySettings.ASSIGNMENT_WRAP), true);
}
else {
return null;
}
}
private boolean isAssignment() {
final IElementType nodeType = myNode.getElementType();
return nodeType == JavaElementType.ASSIGNMENT_EXPRESSION || nodeType == JavaElementType.LOCAL_VARIABLE
|| nodeType == JavaElementType.FIELD;
return myWrapManager.createChildBlockWrap(this, getSettings(), this);
}
@Nullable
@@ -375,14 +338,14 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
if (myNode.getElementType() == JavaElementType.BINARY_EXPRESSION) {
final ASTNode treeParent = myNode.getTreeParent();
if (treeParent != null && treeParent.getElementType() == JavaElementType.BINARY_EXPRESSION) {
return hasTheSamePriority(treeParent);
return FormattingAstUtil.binaryExpressionHasTheSamePriority(myNode, treeParent);
}
}
return false;
}
@Nullable
protected ASTNode processChild(final ArrayList<Block> result,
protected ASTNode processChild(final List<Block> result,
ASTNode child,
Alignment defaultAlignment,
final Wrap defaultWrap,
@@ -391,7 +354,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
@Nullable
protected ASTNode processChild(final ArrayList<Block> result,
protected ASTNode processChild(final List<Block> result,
ASTNode child,
Alignment defaultAlignment,
final Wrap defaultWrap,
@@ -411,7 +374,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
if (childType == JavaTokenType.LBRACE && nodeType == JavaElementType.ARRAY_INITIALIZER_EXPRESSION) {
final Wrap wrap = Wrap.createWrap(getWrapType(mySettings.ARRAY_INITIALIZER_WRAP), false);
child = processParenBlock(JavaTokenType.LBRACE, JavaTokenType.RBRACE,
child = processParenthesisBlock(JavaTokenType.LBRACE, JavaTokenType.RBRACE,
result,
child,
WrappingStrategy.createDoNotWrapCommaStrategy(wrap),
@@ -419,7 +382,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
else if (childType == JavaTokenType.LBRACE && nodeType == JavaElementType.ANNOTATION_ARRAY_INITIALIZER) {
final Wrap wrap = Wrap.createWrap(getWrapType(mySettings.ARRAY_INITIALIZER_WRAP), false);
child = processParenBlock(JavaTokenType.LBRACE, JavaTokenType.RBRACE,
child = processParenthesisBlock(JavaTokenType.LBRACE, JavaTokenType.RBRACE,
result,
child,
WrappingStrategy.createDoNotWrapCommaStrategy(wrap),
@@ -430,7 +393,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
if (mySettings.PREFER_PARAMETERS_WRAP) {
wrap.ignoreParentWraps();
}
child = processParenBlock(result,
child = processParenthesisBlock(result,
child,
WrappingStrategy.createDoNotWrapCommaStrategy(wrap),
mySettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS);
@@ -438,18 +401,18 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
else if (childType == JavaTokenType.LPARENTH && nodeType == JavaElementType.PARAMETER_LIST) {
final Wrap wrap = Wrap.createWrap(getWrapType(mySettings.METHOD_PARAMETERS_WRAP), false);
child = processParenBlock(result, child,
child = processParenthesisBlock(result, child,
WrappingStrategy.createDoNotWrapCommaStrategy(wrap),
mySettings.ALIGN_MULTILINE_PARAMETERS);
}
else if (childType == JavaTokenType.LPARENTH && nodeType == JavaElementType.ANNOTATION_PARAMETER_LIST) {
final Wrap wrap = Wrap.createWrap(getWrapType(mySettings.CALL_PARAMETERS_WRAP), false);
child = processParenBlock(result, child,
child = processParenthesisBlock(result, child,
WrappingStrategy.createDoNotWrapCommaStrategy(wrap),
mySettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS);
}
else if (childType == JavaTokenType.LPARENTH && nodeType == JavaElementType.PARENTH_EXPRESSION) {
child = processParenBlock(result, child,
child = processParenthesisBlock(result, child,
WrappingStrategy.DO_NOT_WRAP,
mySettings.ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION);
}
@@ -501,7 +464,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
return child;
}
private ASTNode processField(final ArrayList<Block> result, ASTNode child, final Alignment defaultAlignment, final Wrap defaultWrap,
private ASTNode processField(final List<Block> result, ASTNode child, final Alignment defaultAlignment, final Wrap defaultWrap,
final Indent childIndent) {
ASTNode lastFieldInGroup = findLastFieldInGroup(child);
if (lastFieldInGroup == child) {
@@ -563,7 +526,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
@Nullable
private ASTNode processTernaryOperationRange(final ArrayList<Block> result,
private ASTNode processTernaryOperationRange(final List<Block> result,
final ASTNode child, final Wrap defaultWrap, final Indent childIndent) {
final ArrayList<Block> localResult = new ArrayList<Block>();
final Wrap wrap = arrangeChildWrap(child, defaultWrap);
@@ -825,186 +788,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
myAnnotationWrap = null;
}
}
final ASTNode parent = child.getTreeParent();
int role = ((CompositeElement)parent).getChildRole(child);
final IElementType nodeType = myNode.getElementType();
if (nodeType == JavaElementType.BINARY_EXPRESSION) {
if (role == ChildRole.OPERATION_SIGN && !mySettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.ROPERAND && mySettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE) return null;
return defaultWrap;
}
final IElementType childType = child.getElementType();
if (childType == JavaElementType.EXTENDS_LIST || childType == JavaElementType.IMPLEMENTS_LIST) {
return Wrap.createWrap(getWrapType(mySettings.EXTENDS_KEYWORD_WRAP), true);
}
else if (childType == JavaElementType.THROWS_LIST) {
return Wrap.createWrap(getWrapType(mySettings.THROWS_KEYWORD_WRAP), true);
}
else if (nodeType == JavaElementType.EXTENDS_LIST || nodeType == JavaElementType.IMPLEMENTS_LIST) {
if (role == ChildRole.REFERENCE_IN_LIST) {
return defaultWrap;
}
else {
return null;
}
}
else if (nodeType == JavaElementType.THROWS_LIST) {
if (role == ChildRole.REFERENCE_IN_LIST) {
return defaultWrap;
}
else {
return null;
}
}
else if (nodeType == JavaElementType.CONDITIONAL_EXPRESSION) {
if (role == ChildRole.COLON && !mySettings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE) return null;
if (role == ChildRole.QUEST && !mySettings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE) return null;
if (role == ChildRole.THEN_EXPRESSION && mySettings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE) return null;
if (role == ChildRole.ELSE_EXPRESSION && mySettings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE) return null;
return defaultWrap;
}
else if (isAssignment()) {
if (role == ChildRole.INITIALIZER_EQ && mySettings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return defaultWrap;
if (role == ChildRole.INITIALIZER_EQ && !mySettings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.OPERATION_SIGN && mySettings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return defaultWrap;
if (role == ChildRole.OPERATION_SIGN && !mySettings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.INITIALIZER && !mySettings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return defaultWrap;
if (role == ChildRole.INITIALIZER && mySettings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.ROPERAND && !mySettings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return defaultWrap;
if (role == ChildRole.ROPERAND && mySettings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.CLOSING_SEMICOLON) return null;
//if (role == ChildRole.TYPE) return defaultWrap;
return defaultWrap;
}
else if (nodeType == JavaElementType.REFERENCE_EXPRESSION) {
if (role == ChildRole.DOT) {
return getReservedWrap(JavaElementType.REFERENCE_EXPRESSION);
}
else {
return defaultWrap;
}
}
else if (nodeType == JavaElementType.FOR_STATEMENT) {
if (role == ChildRole.FOR_INITIALIZATION || role == ChildRole.CONDITION || role == ChildRole.FOR_UPDATE) {
return defaultWrap;
}
if (role == ChildRole.LOOP_BODY) {
final boolean dontWrap = (childType == JavaElementType.CODE_BLOCK || childType == JavaElementType.BLOCK_STATEMENT) &&
mySettings.BRACE_STYLE == CodeStyleSettings.END_OF_LINE;
return Wrap.createWrap(dontWrap ? WrapType.NONE : WrapType.NORMAL, true);
}
else {
return null;
}
}
else if (nodeType == JavaElementType.METHOD) {
if (role == ChildRole.THROWS_LIST) {
return defaultWrap;
}
else {
return null;
}
}
else if (nodeType == JavaElementType.MODIFIER_LIST) {
if (childType == JavaElementType.ANNOTATION) {
return getReservedWrap(JavaElementType.MODIFIER_LIST);
}
ASTNode prevElement = getPrevElement(child);
if (prevElement != null && prevElement.getElementType() == JavaElementType.ANNOTATION) {
return getReservedWrap(JavaElementType.MODIFIER_LIST);
}
else {
return null;
}
}
else if (nodeType == JavaElementType.ASSERT_STATEMENT) {
if (role == ChildRole.CONDITION) {
return defaultWrap;
}
if (role == ChildRole.ASSERT_DESCRIPTION && !mySettings.ASSERT_STATEMENT_COLON_ON_NEXT_LINE) {
return defaultWrap;
}
if (role == ChildRole.COLON && mySettings.ASSERT_STATEMENT_COLON_ON_NEXT_LINE) {
return defaultWrap;
}
return null;
}
else if (nodeType == JavaElementType.CODE_BLOCK) {
if (role == ChildRole.STATEMENT_IN_BLOCK) {
return defaultWrap;
}
else {
return null;
}
}
else if (nodeType == JavaElementType.IF_STATEMENT) {
if (childType == JavaElementType.IF_STATEMENT && role == ChildRole.ELSE_BRANCH && getSettings().SPECIAL_ELSE_IF_TREATMENT) {
return Wrap.createWrap(WrapType.NONE, false);
}
if (role == ChildRole.THEN_BRANCH || role == ChildRole.ELSE_BRANCH) {
if (childType == JavaElementType.BLOCK_STATEMENT) {
return null;
}
else {
return Wrap.createWrap(WrapType.NORMAL, true);
}
}
}
else if (nodeType == JavaElementType.FOREACH_STATEMENT || nodeType == JavaElementType.WHILE_STATEMENT) {
if (role == ChildRole.LOOP_BODY) {
if (childType == JavaElementType.BLOCK_STATEMENT) {
return null;
}
else {
return Wrap.createWrap(WrapType.NORMAL, true);
}
}
}
else if (nodeType == JavaElementType.DO_WHILE_STATEMENT) {
if (role == ChildRole.LOOP_BODY) {
return Wrap.createWrap(WrapType.NORMAL, true);
} else if (role == ChildRole.WHILE_KEYWORD) {
return Wrap.createWrap(WrapType.NORMAL, true);
}
} else if (nodeType == JavaElementType.ANNOTATION_ARRAY_INITIALIZER) {
if (role == ChildRole.ANNOTATION_VALUE) {
return Wrap.createWrap(WrapType.NORMAL, true);
}
}
return defaultWrap;
}
@Nullable
private static ASTNode getPrevElement(final ASTNode child) {
ASTNode result = child.getTreePrev();
while (result != null && result.getElementType() == TokenType.WHITE_SPACE) {
result = result.getTreePrev();
}
return result;
}
private boolean hasTheSamePriority(final ASTNode node) {
if (node == null) return false;
if (node.getElementType() != JavaElementType.BINARY_EXPRESSION) {
return false;
}
else {
final PsiBinaryExpression expr1 = (PsiBinaryExpression)SourceTreeToPsiMap.treeElementToPsi(myNode);
final PsiBinaryExpression expr2 = (PsiBinaryExpression)SourceTreeToPsiMap.treeElementToPsi(node);
final PsiJavaToken op1 = expr1.getOperationSign();
final PsiJavaToken op2 = expr2.getOperationSign();
return op1.getTokenType() == op2.getTokenType();
}
return myWrapManager.arrangeChildWrap(child, myNode, getSettings(), defaultWrap, this);
}
private static WrapType getWrapType(final int wrap) {
@@ -1020,23 +804,19 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
}
private ASTNode processParenBlock(List<Block> result,
ASTNode child,
WrappingStrategy wrappingStrategy,
final boolean doAlign) {
private ASTNode processParenthesisBlock(List<Block> result, ASTNode child,WrappingStrategy wrappingStrategy, final boolean doAlign) {
myUseChildAttributes = true;
final IElementType from = JavaTokenType.LPARENTH;
final IElementType to = JavaTokenType.RPARENTH;
return processParenBlock(from, to, result, child, wrappingStrategy, doAlign);
return processParenthesisBlock(from, to, result, child, wrappingStrategy, doAlign);
}
private ASTNode processParenBlock(final IElementType from,
private ASTNode processParenthesisBlock(final IElementType from,
final IElementType to, final List<Block> result, ASTNode child,
final WrappingStrategy wrappingStrategy, final boolean doAlign
) {
@@ -1049,7 +829,6 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
boolean isAfterIncomplete = false;
ASTNode prev = child;
int startOffset = child.getTextRange().getStartOffset();
while (child != null) {
isAfterIncomplete = isAfterIncomplete || child.getElementType() == TokenType.ERROR_ELEMENT ||
child.getElementType() == JavaElementType.EMPTY_EXPRESSION;
@@ -1066,10 +845,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
else {
final IElementType elementType = child.getElementType();
result.add(createJavaBlock(child, mySettings, internalIndent,
wrappingStrategy.getWrap(elementType),
alignmentStrategy.getAlignment(elementType),
startOffset));
processChild(result, child, alignmentStrategy.getAlignment(elementType), wrappingStrategy.getWrap(elementType), internalIndent);
if (to == null) {//process only one statement
return child;
}
@@ -1077,7 +853,6 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
isAfterIncomplete = false;
}
prev = child;
startOffset += child.getTextLength();
child = child.getTreeNext();
}
@@ -1202,9 +977,31 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
return false;
}
protected abstract Wrap getReservedWrap(final IElementType elementType);
/**
* <b>Note:</b> this method is considered to be a legacy heritage and is assumed to be removed as soon as formatting processing
* is refactored
*
* @param elementType target element type
* @return <code>null</code> all the time
*/
public Wrap getReservedWrap(IElementType elementType) {
return null;
}
protected abstract void setReservedWrap(final Wrap reservedWrap, final IElementType operationType);
/**
* Defines contract for associating operation type and particular wrap instance. I.e. given wrap object <b>may</b> be returned
* from subsequent {@link #getReservedWrap(IElementType)} call if given operation type is used as an argument there.
* <p/>
* Default implementation ({@link AbstractJavaBlock#setReservedWrap(Wrap, IElementType)}) does nothing.
* <p/>
* <b>Note:</b> this method is considered to be a legacy heritage and is assumed to be removed as soon as formatting processing
* is refactored
*
* @param reservedWrap reserved wrap instance
* @param operationType target operation type to associate with the given wrap instance
*/
protected void setReservedWrap(final Wrap reservedWrap, final IElementType operationType) {
}
@Nullable
protected static ASTNode getTreeNode(final Block child2) {
@@ -71,7 +71,7 @@ public class BlockContainingJavaBlock extends AbstractJavaBlock{
}
}
private int calcNewState(final ASTNode child, final int state) {
private static int calcNewState(final ASTNode child, final int state) {
if (state == BEFORE_FIRST) {
if (child.getElementType() == ElementType.ELSE_KEYWORD) {
return AFTER_ELSE;
@@ -152,13 +152,13 @@ public class BlockContainingJavaBlock extends AbstractJavaBlock{
return Indent.getContinuationIndent();
}
private boolean isSimpleStatement(final ASTNode child) {
private static boolean isSimpleStatement(final ASTNode child) {
if (child.getElementType() == ElementType.BLOCK_STATEMENT) return false;
if (!ElementType.STATEMENT_BIT_SET.contains(child.getElementType())) return false;
return isStatement(child, child.getTreeParent());
}
private boolean isPartOfCodeBlock(final ASTNode child) {
private static boolean isPartOfCodeBlock(final ASTNode child) {
if (child == null) return false;
if (child.getElementType() == ElementType.BLOCK_STATEMENT) return true;
if (child.getElementType() == ElementType.CODE_BLOCK) return true;
@@ -168,12 +168,7 @@ public class BlockContainingJavaBlock extends AbstractJavaBlock{
return child.getElementType() == JavaDocElementType.DOC_COMMENT;
}
protected Wrap getReservedWrap(final IElementType elementType) {
return null;
}
protected void setReservedWrap(final Wrap reservedWrap, final IElementType operationType) {
}
@NotNull
public ChildAttributes getChildAttributes(final int newChildIndex) {
@@ -27,6 +27,7 @@ import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.StdTokenSets;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -97,6 +98,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
}
}
@Nullable
private ASTNode composeCodeBlock(final ArrayList<Block> result, ASTNode child, final Indent indent) {
final ArrayList<Block> localResult = new ArrayList<Block>();
processChild(localResult, child, null, null, Indent.getNoneIndent());
@@ -125,6 +127,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
return result;
}
@Nullable
private ASTNode processCaseAndStatementAfter(final ArrayList<Block> result,
ASTNode child,
final Alignment childAlignment,
@@ -159,7 +162,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
return null;
}
private boolean isBreakOrReturn(final ASTNode child) {
private static boolean isBreakOrReturn(final ASTNode child) {
IElementType elementType = child.getElementType();
return JavaElementType.BREAK_STATEMENT == elementType || JavaElementType.RETURN_STATEMENT == elementType;
}
@@ -193,7 +196,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
return result;
}
private int calcNewState(final ASTNode child, int state) {
private static int calcNewState(final ASTNode child, int state) {
switch (state) {
case BEFORE_FIRST: {
if (StdTokenSets.COMMENT_BIT_SET.contains(child.getElementType())) {
@@ -218,7 +221,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
return INSIDE_BODY;
}
private boolean isLBrace(final ASTNode child) {
private static boolean isLBrace(final ASTNode child) {
return child.getElementType() == ElementType.LBRACE;
}
@@ -250,7 +253,7 @@ public class CodeBlockBlock extends AbstractJavaBlock {
}
}
private boolean isRBrace(final ASTNode child) {
private static boolean isRBrace(final ASTNode child) {
return child.getElementType() == ElementType.RBRACE;
}
@@ -269,11 +272,4 @@ public class CodeBlockBlock extends AbstractJavaBlock {
}
}
}
protected Wrap getReservedWrap(final IElementType elementType) {
return null;
}
protected void setReservedWrap(final Wrap reservedWrap, final IElementType operationType) {
}
}
@@ -20,7 +20,6 @@ import com.intellij.lang.ASTNode;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -48,13 +47,6 @@ public class DocCommentBlock extends AbstractJavaBlock{
}
protected Wrap getReservedWrap(final IElementType elementType) {
return null;
}
protected void setReservedWrap(final Wrap reservedWrap, final IElementType operationType) {
}
@NotNull
public ChildAttributes getChildAttributes(final int newChildIndex) {
return new ChildAttributes(Indent.getSpaceIndent(1), null);
@@ -23,7 +23,6 @@ import com.intellij.lang.ASTNode;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.tree.IElementType;
import java.util.ArrayList;
import java.util.List;
@@ -77,11 +76,4 @@ public class ExtendsListBlock extends AbstractJavaBlock{
}
return false;
}
protected Wrap getReservedWrap(final IElementType elementType) {
return null;
}
protected void setReservedWrap(final Wrap reservedWrap, final IElementType operationType) {
}
}
@@ -0,0 +1,92 @@
/*
* 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.psi.formatter.java;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiBinaryExpression;
import com.intellij.psi.TokenType;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Set;
import static java.util.Arrays.asList;
/**
* Contains various utility methods for <code>AST</code> processing during code formatting.
*
* @author Denis Zhdanov
* @since Apr 21, 2010 4:02:17 PM
*/
public class FormattingAstUtil {
/** Holds type of AST elements that are considered to be assignments. */
private static final Set<IElementType> ASSIGNMENT_ELEMENT_TYPES = new HashSet<IElementType>(asList(
JavaElementType.ASSIGNMENT_EXPRESSION, JavaElementType.LOCAL_VARIABLE, JavaElementType.FIELD
));
private FormattingAstUtil() {
}
/**
* Tries to get previous non-white space <code>AST</code> node for the given one.
*
* @param node base node which left non-white space sibling is to be found
* @return left non-white space sibling of the given node if any; <code>null</code> otherwise
*/
@Nullable
public static ASTNode getPrevElement(final ASTNode node) {
ASTNode result = node.getTreePrev();
while (result != null && result.getElementType() == TokenType.WHITE_SPACE) {
result = result.getTreePrev();
}
return result;
}
/**
* Allows to answer if given node wraps assignement operation.
*
* @param node node to check
* @return <code>true</code> if given node wraps assignement operation; <code>false</code> otherwise
*/
public static boolean isAssignment(ASTNode node) {
return ASSIGNMENT_ELEMENT_TYPES.contains(node.getElementType());
}
/**
* Allows to check if given <code>AST</code> nodes refer to binary expressions and have the same priority.
*
* @param node1 node to check
* @param node2 node to check
* @return <code>true</code> if given nodes are binary expressions and have the same priority;
* <code>false</code> otherwise
*/
public static boolean binaryExpressionHasTheSamePriority(ASTNode node1, ASTNode node2) {
if (node1 == null || node2 == null) {
return false;
}
if (node1.getElementType() != JavaElementType.BINARY_EXPRESSION || node2.getElementType() != JavaElementType.BINARY_EXPRESSION) {
return false;
}
PsiBinaryExpression expression1 = (PsiBinaryExpression)SourceTreeToPsiMap.treeElementToPsi(node1);
PsiBinaryExpression expression2 = (PsiBinaryExpression)SourceTreeToPsiMap.treeElementToPsi(node2);
return expression1.getOperationSign().getTokenType() == expression2.getOperationSign().getTokenType();
}
}
@@ -21,7 +21,6 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.FormatterUtil;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -46,7 +45,7 @@ public class LabeledJavaBlock extends AbstractJavaBlock{
result.add(createJavaBlock(child, mySettings, currentIndent, currentWrap, null));
if (child.getElementType() == ElementType.COLON) {
currentIndent = Indent.getNoneIndent();
currentWrap =Wrap.createWrap(Wrap.ALWAYS, true);
currentWrap =Wrap.createWrap(WrapType.ALWAYS, true);
}
}
child = child.getTreeNext();
@@ -62,13 +61,6 @@ public class LabeledJavaBlock extends AbstractJavaBlock{
}
}
protected Wrap getReservedWrap(final IElementType elementType) {
return null;
}
protected void setReservedWrap(final Wrap reservedWrap, final IElementType operationType) {
}
@Override
@NotNull
public ChildAttributes getChildAttributes(final int newChildIndex) {
@@ -21,7 +21,6 @@ import com.intellij.formatting.Alignment;
import com.intellij.formatting.Indent;
import com.intellij.formatting.Block;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.tree.IElementType;
import java.util.List;
@@ -33,11 +32,4 @@ public class MethodCallExpressionBlock extends AbstractJavaBlock{
protected List<Block> buildChildren() {
return null;
}
protected Wrap getReservedWrap(final IElementType elementType) {
return null;
}
protected void setReservedWrap(final Wrap reservedWrap, final IElementType operationType) {
}
}
@@ -70,7 +70,7 @@ public class SimpleJavaBlock extends AbstractJavaBlock {
if (astNode != child && child != null) {
offset = child.getTextRange().getStartOffset();
}
if (indent != null && !(myNode.getPsi() instanceof PsiFile) && child.getElementType() != ElementType.MODIFIER_LIST) {
if (indent != null && !(myNode.getPsi() instanceof PsiFile) && child != null && child.getElementType() != ElementType.MODIFIER_LIST) {
indent = Indent.getContinuationIndent();
}
//indent = FormatterEx.getInstance().getContinuationIndent();
@@ -107,10 +107,12 @@ public class SimpleJavaBlock extends AbstractJavaBlock {
}
}
protected Wrap getReservedWrap(final IElementType elementType) {
@Override
public Wrap getReservedWrap(final IElementType elementType) {
return myReservedWrap.get(elementType);
}
@Override
protected void setReservedWrap(final Wrap reservedWrap, final IElementType operationType) {
myReservedWrap.put(operationType, reservedWrap);
}
@@ -0,0 +1,100 @@
/*
* 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.psi.formatter.java.wrap;
import com.intellij.formatting.ASTBlock;
import com.intellij.formatting.Block;
import com.intellij.formatting.Wrap;
import com.intellij.lang.ASTNode;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.java.wrap.impl.JavaChildBlockWrapFactory;
import com.intellij.psi.formatter.java.wrap.impl.JavaChildWrapArranger;
import org.jetbrains.annotations.Nullable;
/**
* Defines common contract for {@link Wrap wraps} manipulation during java {@link Block blockes} processing
* <p/>
* This class is intended to serve as a facade for various fine-grained wrap processing classes.
* <p/>
* This class is not singleton but it's thread-safe and provides single-point-of-usage field {@link #INSTANCE}.
* <p/>
* Thread-safe.
*
* @author Denis Zhdanov
* @since Apr 21, 2010 2:19:17 PM
*/
public class JavaWrapManager {
/** Single-point-of-usage field. */
public static final JavaWrapManager INSTANCE = new JavaWrapManager();
private final JavaChildWrapArranger myChildArranger;
private final JavaChildBlockWrapFactory myChildBlockFactory;
/**
* Creates new <code>JavaWrapManager</code> object with default wrapping services.
*/
public JavaWrapManager() {
this(new JavaChildWrapArranger(), new JavaChildBlockWrapFactory());
}
public JavaWrapManager(JavaChildWrapArranger childWrapArranger, JavaChildBlockWrapFactory childBlockWrapFactory) {
myChildArranger = childWrapArranger;
myChildBlockFactory = childBlockWrapFactory;
}
/**
* Tries to define the wrap to use for the {@link Block block} for the given <code>'child'</code> node. It's assumed that
* given <code>'child'</code> node is descendant (direct or indirect) of the given <code>'parent'</code> node.
* I.e. <code>'parent'</code> node defines usage context for the <code>'child'</code> node.
*
* @param child child node which {@link Wrap wrap} is to be defined
* @param parent direct or indirect parent of the given <code>'child'</code> node. Defines usage context
* of <code>'child'</code> node processing
* @param settings code style settings to use during wrap definition
* @param suggestedWrap wrap suggested to use by clients of current class. I.e. those clients offer wrap to
* use based on their information about current processing state. However, it's possible
* that they don't know details of fine-grained wrap definition algorithm encapsulated
* at the current class. Hence, this method takes suggested wrap into consideration but
* is not required to use it all the time node based on the given parameters
* @param reservedWrapsProvider reserved {@code 'element type -> wrap instance'} mappings provider. <b>Note:</b> this
* argument is considered to be a part of legacy heritage and is intended to be removed as
* soon as formatting code refactoring is done
* @return wrap to use for the given <code>'child'</code> node if it's possible to define the one;
* <code>null</code> otherwise
*/
@Nullable
public Wrap arrangeChildWrap(ASTNode child, ASTNode parent, CodeStyleSettings settings, Wrap suggestedWrap,
ReservedWrapsProvider reservedWrapsProvider)
{
return myChildArranger.arrange(child, parent, settings, suggestedWrap, reservedWrapsProvider);
}
/**
* Creates {@link Wrap wrap} to be used with the children blocks of the the given block.
*
* @param block target block which sub-blocks should use wrap created by the current method
* @param settings code formatting settings to consider during wrap construction
* @param reservedWrapsProvider reserved {@code 'element type -> wrap instance'} mappings provider. <b>Note:</b> this
* argument is considered to be a part of legacy heritage and is intended to be removed as
* soon as formatting code refactoring is done
* @return wrap to use for the sub-blocks of the given block
*/
@Nullable
public Wrap createChildBlockWrap(ASTBlock block, CodeStyleSettings settings, ReservedWrapsProvider reservedWrapsProvider) {
return myChildBlockFactory.create(block, settings, reservedWrapsProvider);
}
}
@@ -0,0 +1,42 @@
/*
* 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.psi.formatter.java.wrap;
import com.intellij.formatting.Wrap;
import com.intellij.psi.formatter.java.AbstractJavaBlock;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.Nullable;
/**
* Defines contract for using predefined reserved wraps.
* <p/>
* <b>Note:</b> this interface is introduced for encapsulating legacy {@link AbstractJavaBlock#getReservedWrap(IElementType)}
* method and most probably will be removed as soon as formatting stuff is refactored.
*
* @author Denis Zhdanov
* @since Apr 21, 2010 3:43:17 PM
*/
public interface ReservedWrapsProvider {
/**
* Allows to retrieve predefined {@link Wrap} object for the given element type if any.
*
* @param elementType target element type
* @return predefined wrap for the given element type if any; <code>null</code> otherwise
*/
@Nullable
Wrap getReservedWrap(IElementType elementType);
}
@@ -0,0 +1,94 @@
/*
* 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.psi.formatter.java.wrap.impl;
import com.intellij.formatting.ASTBlock;
import com.intellij.formatting.Wrap;
import com.intellij.formatting.WrapType;
import com.intellij.lang.ASTNode;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.java.FormattingAstUtil;
import com.intellij.psi.formatter.java.wrap.ReservedWrapsProvider;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.Nullable;
/**
* Encapsulates algorithm of construction {@link Wrap wraps} for sub-blocks of particular {@link ASTBlock block} taking into
* consideration current formatting settings.
* <p/>
* Thread-safe.
*
* @author Denis Zhdanov
* @since Apr 21, 2010 4:49:49 PM
*/
public class JavaChildBlockWrapFactory {
/**
* Creates {@link Wrap wrap} to be used with the children blocks of the the given block.
*
* @param block target block which sub-blocks should use wrap created by the current method
* @param settings code formatting settings to consider during wrap construction
* @param reservedWrapsProvider reserved {@code 'element type -> wrap instance'} mappings provider. <b>Note:</b> this
* argument is considered to be a part of legacy heritage and is intended to be removed as
* soon as formatting code refactoring is done
* @return wrap to use for the sub-blocks of the given block
*/
@Nullable
public Wrap create(ASTBlock block, CodeStyleSettings settings, ReservedWrapsProvider reservedWrapsProvider) {
ASTNode node = block.getNode();
Wrap wrap = block.getWrap();
final IElementType nodeType = node.getElementType();
if (nodeType == JavaElementType.EXTENDS_LIST || nodeType == JavaElementType.IMPLEMENTS_LIST) {
return Wrap.createWrap(settings.EXTENDS_LIST_WRAP, false);
}
else if (nodeType == JavaElementType.BINARY_EXPRESSION) {
Wrap actualWrap = wrap != null ? wrap : reservedWrapsProvider.getReservedWrap(JavaElementType.BINARY_EXPRESSION);
if (actualWrap == null) {
return Wrap.createWrap(settings.BINARY_OPERATION_WRAP, false);
}
else {
if (!FormattingAstUtil.binaryExpressionHasTheSamePriority(node, node.getTreeParent())) {
return Wrap.createChildWrap(actualWrap, WrapType.byLegacyRepresentation(settings.BINARY_OPERATION_WRAP), false);
}
else {
return actualWrap;
}
}
}
else if (nodeType == JavaElementType.CONDITIONAL_EXPRESSION) {
return Wrap.createWrap(settings.TERNARY_OPERATION_WRAP, false);
}
else if (nodeType == JavaElementType.ASSERT_STATEMENT) {
return Wrap.createWrap(settings.ASSERT_STATEMENT_WRAP, false);
}
else if (nodeType == JavaElementType.FOR_STATEMENT) {
return Wrap.createWrap(settings.FOR_STATEMENT_WRAP, false);
}
else if (nodeType == JavaElementType.THROWS_LIST) {
return Wrap.createWrap(settings.THROWS_LIST_WRAP, true);
}
else if (nodeType == JavaElementType.CODE_BLOCK) {
return Wrap.createWrap(Wrap.NORMAL, false);
}
else if (FormattingAstUtil.isAssignment(node)) {
return Wrap.createWrap(settings.ASSIGNMENT_WRAP, true);
}
else {
return null;
}
}
}
@@ -0,0 +1,227 @@
/*
* 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.psi.formatter.java.wrap.impl;
import com.intellij.formatting.Wrap;
import com.intellij.formatting.WrapType;
import com.intellij.lang.ASTNode;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.java.FormattingAstUtil;
import com.intellij.psi.formatter.java.wrap.JavaWrapManager;
import com.intellij.psi.formatter.java.wrap.ReservedWrapsProvider;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.Nullable;
/**
* Encapsulates implementation of
* {@link JavaWrapManager#arrangeChildWrap(ASTNode, ASTNode, CodeStyleSettings, Wrap, ReservedWrapsProvider)}.
* <p/>
* Thread-safe.
*
* @author Denis Zhdanov
* @since Apr 21, 2010 2:30:29 PM
*/
public class JavaChildWrapArranger {
/**
* Provides implementation of {@link JavaWrapManager#arrangeChildWrap(ASTNode, ASTNode, CodeStyleSettings, Wrap, ReservedWrapsProvider)}
* method.
*
* @param child child node which {@link Wrap wrap} is to be defined
* @param parent direct or indirect parent of the given <code>'child'</code> node. Defines usage context
* of <code>'child'</code> node processing
* @param settings code style settings to use during wrap definition
* @param suggestedWrap wrap suggested to use by clients of current class. I.e. those clients offer wrap to
* use based on their information about current processing state. However, it's possible
* that they don't know details of fine-grained wrap definition algorithm encapsulated
* at the current class. Hence, this method takes suggested wrap into consideration but
* is not required to use it all the time node based on the given parameters
* @param reservedWrapsProvider reserved {@code 'element type -> wrap instance'} mappings provider. <b>Note:</b> this
* argument is considered to be a part of legacy heritage and is intended to be removed as
* soon as formatting code refactoring is done
* @return wrap to use for the given <code>'child'</code> node if it's possible to define the one;
* <code>null</code> otherwise
*/
@SuppressWarnings({"MethodMayBeStatic"})
@Nullable
public Wrap arrange(ASTNode child, ASTNode parent, CodeStyleSettings settings, Wrap suggestedWrap,
ReservedWrapsProvider reservedWrapsProvider)
{
final ASTNode directParent = child.getTreeParent();
int role = ((CompositeElement)directParent).getChildRole(child);
final IElementType nodeType = parent.getElementType();
if (nodeType == JavaElementType.BINARY_EXPRESSION) {
if (role == ChildRole.OPERATION_SIGN && !settings.BINARY_OPERATION_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.ROPERAND && settings.BINARY_OPERATION_SIGN_ON_NEXT_LINE) return null;
return suggestedWrap;
}
final IElementType childType = child.getElementType();
if (childType == JavaElementType.EXTENDS_LIST || childType == JavaElementType.IMPLEMENTS_LIST) {
return Wrap.createWrap(settings.EXTENDS_KEYWORD_WRAP, true);
}
else if (childType == JavaElementType.THROWS_LIST) {
return Wrap.createWrap(settings.THROWS_KEYWORD_WRAP, true);
}
else if (nodeType == JavaElementType.EXTENDS_LIST || nodeType == JavaElementType.IMPLEMENTS_LIST) {
if (role == ChildRole.REFERENCE_IN_LIST) {
return suggestedWrap;
}
else {
return null;
}
}
else if (nodeType == JavaElementType.THROWS_LIST) {
if (role == ChildRole.REFERENCE_IN_LIST) {
return suggestedWrap;
}
else {
return null;
}
}
else if (nodeType == JavaElementType.CONDITIONAL_EXPRESSION) {
if (role == ChildRole.COLON && !settings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE) return null;
if (role == ChildRole.QUEST && !settings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE) return null;
if (role == ChildRole.THEN_EXPRESSION && settings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE) return null;
if (role == ChildRole.ELSE_EXPRESSION && settings.TERNARY_OPERATION_SIGNS_ON_NEXT_LINE) return null;
return suggestedWrap;
}
else if (FormattingAstUtil.isAssignment(parent)) {
if (role == ChildRole.INITIALIZER_EQ && settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return suggestedWrap;
if (role == ChildRole.INITIALIZER_EQ && !settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.OPERATION_SIGN && settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return suggestedWrap;
if (role == ChildRole.OPERATION_SIGN && !settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.INITIALIZER && !settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return suggestedWrap;
if (role == ChildRole.INITIALIZER && settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.ROPERAND && !settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return suggestedWrap;
if (role == ChildRole.ROPERAND && settings.PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE) return null;
if (role == ChildRole.CLOSING_SEMICOLON) return null;
//if (role == ChildRole.TYPE) return suggestedWrap;
return suggestedWrap;
}
else if (nodeType == JavaElementType.REFERENCE_EXPRESSION) {
if (role == ChildRole.DOT) {
return reservedWrapsProvider.getReservedWrap(JavaElementType.REFERENCE_EXPRESSION);
}
else {
return suggestedWrap;
}
}
else if (nodeType == JavaElementType.FOR_STATEMENT) {
if (role == ChildRole.FOR_INITIALIZATION || role == ChildRole.CONDITION || role == ChildRole.FOR_UPDATE) {
return suggestedWrap;
}
if (role == ChildRole.LOOP_BODY) {
final boolean dontWrap = (childType == JavaElementType.CODE_BLOCK || childType == JavaElementType.BLOCK_STATEMENT) &&
settings.BRACE_STYLE == CodeStyleSettings.END_OF_LINE;
return Wrap.createWrap(dontWrap ? WrapType.NONE : WrapType.NORMAL, true);
}
else {
return null;
}
}
else if (nodeType == JavaElementType.METHOD) {
if (role == ChildRole.THROWS_LIST) {
return suggestedWrap;
}
else {
return null;
}
}
else if (nodeType == JavaElementType.MODIFIER_LIST) {
if (childType == JavaElementType.ANNOTATION) {
return reservedWrapsProvider.getReservedWrap(JavaElementType.MODIFIER_LIST);
}
ASTNode prevElement = FormattingAstUtil.getPrevElement(child);
if (prevElement != null && prevElement.getElementType() == JavaElementType.ANNOTATION) {
return reservedWrapsProvider.getReservedWrap(JavaElementType.MODIFIER_LIST);
}
else {
return null;
}
}
else if (nodeType == JavaElementType.ASSERT_STATEMENT) {
if (role == ChildRole.CONDITION) {
return suggestedWrap;
}
if (role == ChildRole.ASSERT_DESCRIPTION && !settings.ASSERT_STATEMENT_COLON_ON_NEXT_LINE) {
return suggestedWrap;
}
if (role == ChildRole.COLON && settings.ASSERT_STATEMENT_COLON_ON_NEXT_LINE) {
return suggestedWrap;
}
return null;
}
else if (nodeType == JavaElementType.CODE_BLOCK) {
if (role == ChildRole.STATEMENT_IN_BLOCK) {
return suggestedWrap;
}
else {
return null;
}
}
else if (nodeType == JavaElementType.IF_STATEMENT) {
if (childType == JavaElementType.IF_STATEMENT && role == ChildRole.ELSE_BRANCH && settings.SPECIAL_ELSE_IF_TREATMENT) {
return Wrap.createWrap(WrapType.NONE, false);
}
if (role == ChildRole.THEN_BRANCH || role == ChildRole.ELSE_BRANCH) {
if (childType == JavaElementType.BLOCK_STATEMENT) {
return null;
}
else {
return Wrap.createWrap(WrapType.NORMAL, true);
}
}
}
else if (nodeType == JavaElementType.FOREACH_STATEMENT || nodeType == JavaElementType.WHILE_STATEMENT) {
if (role == ChildRole.LOOP_BODY) {
if (childType == JavaElementType.BLOCK_STATEMENT) {
return null;
}
else {
return Wrap.createWrap(WrapType.NORMAL, true);
}
}
}
else if (nodeType == JavaElementType.DO_WHILE_STATEMENT) {
if (role == ChildRole.LOOP_BODY) {
return Wrap.createWrap(WrapType.NORMAL, true);
} else if (role == ChildRole.WHILE_KEYWORD) {
return Wrap.createWrap(WrapType.NORMAL, true);
}
} else if (nodeType == JavaElementType.ANNOTATION_ARRAY_INITIALIZER) {
if (suggestedWrap != null) {
return suggestedWrap;
}
if (role == ChildRole.ANNOTATION_VALUE) {
return Wrap.createWrap(WrapType.NORMAL, true);
}
}
return suggestedWrap;
}
}
@@ -30,6 +30,7 @@ import com.intellij.psi.scope.ElementClassFilter;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.scope.processor.FilterScopeProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.CharTable;
@@ -112,7 +113,17 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
PsiParameter parameter = parameters[j];
PsiType type1 = TypeConversionUtil.erasure(parameter.getType());
String type2 = signature[j];
if (!Comparing.strEqual(type1.getPresentableText(), type2) && !Comparing.strEqual(type1.getCanonicalText(), type2)) continue nextMethod;
if (!Comparing.strEqual(type1.getPresentableText(), type2) && !Comparing.strEqual(type1.getCanonicalText(), type2)) {
String shortName = "";
PsiClass psiClass = PsiUtil.resolveClassInType(type1);
while (psiClass != null) {
shortName = psiClass.getName() + (shortName.length() > 0 ? "." + shortName : "");
psiClass = PsiTreeUtil.getParentOfType(psiClass, PsiClass.class);
}
if (!Comparing.strEqual(shortName, type2)) {
continue nextMethod;
}
}
}
return new MyReference(method) {
@@ -91,6 +91,7 @@ public class CreateClassUtil {
else {
final FileTemplateManager fileTemplateManager = FileTemplateManager.getInstance();
FileTemplate fileTemplate = fileTemplateManager.getJ2eeTemplate(templateName);
LOG.assertTrue(fileTemplate != null, templateName + " not found");
final String text = fileTemplate.getText(attributes);
aClass = JavaCreateFromTemplateHandler.createClassOrInterface(project, directory, text, true, fileTemplate.getExtension());
}
@@ -28,6 +28,9 @@ import org.jetbrains.annotations.Nullable;
public class JavaInheritanceWeigher extends ProximityWeigher {
public Comparable weigh(@NotNull final PsiElement element, final ProximityLocation location) {
if (element instanceof PsiClass && isTooGeneral((PsiClass)element)) return false;
if (element instanceof PsiMethod && isTooGeneral(((PsiMethod)element).getContainingClass())) return false;
final PsiElement position = location.getPosition();
PsiClass placeClass = PsiTreeUtil.getContextOfType(element, PsiClass.class, false);
if (position.getParent() instanceof PsiReferenceExpression) {
@@ -43,9 +46,8 @@ public class JavaInheritanceWeigher extends ProximityWeigher {
}
}
if (element instanceof PsiClass && isTooGeneral((PsiClass)element)) return false;
if (element instanceof PsiMethod && isTooGeneral(((PsiMethod)element).getContainingClass())) return false;
if (placeClass == null) return false;
PsiClass contextClass = PsiTreeUtil.getContextOfType(position, PsiClass.class, false);
while (contextClass != null) {
PsiClass elementClass = placeClass;
@@ -100,6 +100,7 @@ public class JavaRefactoringSettings implements PersistentStateComponent<JavaRef
@SuppressWarnings({"WeakerAccess"}) public boolean RENAME_INHERITORS = true;
@SuppressWarnings({"WeakerAccess"}) public boolean RENAME_PARAMETER_IN_HIERARCHY = true;
@SuppressWarnings({"WeakerAccess"}) public boolean RENAME_VARIABLES = true;
@SuppressWarnings({"WeakerAccess"}) public boolean RENAME_TESTS = true;
public static JavaRefactoringSettings getInstance() {
return ServiceManager.getService(JavaRefactoringSettings.class);
@@ -136,4 +137,12 @@ public class JavaRefactoringSettings implements PersistentStateComponent<JavaRef
public void loadState(JavaRefactoringSettings state) {
XmlSerializerUtil.copyBean(state, this);
}
public boolean isToRenameTests() {
return RENAME_TESTS;
}
public void setRenameTests(boolean renameTests) {
this.RENAME_TESTS = renameTests;
}
}
@@ -35,10 +35,11 @@ public class ChangeSignatureTargetUtil {
return PsiTreeUtil.getParentOfType(element, PsiMethod.class);
}
final PsiMethodCallExpression expression = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
final PsiCallExpression expression = PsiTreeUtil.getParentOfType(element, PsiCallExpression.class);
if (expression != null) {
assert element != null;
final PsiExpression qualifierExpression = expression.getMethodExpression().getQualifierExpression();
final PsiExpression qualifierExpression = expression instanceof PsiMethodCallExpression ? ((PsiMethodCallExpression)expression).getMethodExpression().getQualifierExpression()
: expression instanceof PsiNewExpression ? ((PsiNewExpression)expression).getQualifier() : null;
if (PsiTreeUtil.isAncestor(qualifierExpression, element, false)) {
final PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(qualifierExpression, PsiExpressionList.class);
if (expressionList != null) {
@@ -110,6 +110,8 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor {
}
for (PsiMethod method : methods) {
method.accept(visitor);
//do not include method's type parameters in class signature
typeParamSet.removeAll(Arrays.asList(method.getTypeParameters()));
}
typeParams.addAll(typeParamSet);
}
@@ -84,5 +84,19 @@ public class MoveJavaFileHandler extends MoveFileHandler {
@Override
public void updateMovedFile(PsiFile file) throws IncorrectOperationException {
ChangeContextUtil.decodeContextInfo(file, null, null);
final PsiDirectory containingDirectory = file.getContainingDirectory();
if (containingDirectory != null) {
final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(containingDirectory);
if (aPackage != null) {
final PsiPackageStatement packageStatement =
JavaPsiFacade.getElementFactory(file.getProject()).createPackageStatement(aPackage.getQualifiedName());
if (file instanceof PsiJavaFile) {
final PsiPackageStatement filePackageStatement = ((PsiJavaFile)file).getPackageStatement();
if (filePackageStatement != null) {
filePackageStatement.getPackageReference().replace(packageStatement.getPackageReference());
}
}
}
}
}
}
@@ -33,7 +33,8 @@ public class JavaMoveFilesOrDirectoriesHandler extends MoveFilesOrDirectoriesHan
allJava &= JavaCopyFilesOrDirectoriesHandler.hasPackages((PsiDirectory)element);
}
else if (element instanceof PsiFile) {
allJava &= element instanceof PsiJavaFile && !JspPsiUtil.isInJspFile(element) && !CollectHighlightsUtil.isOutsideSourceRootJavaFile((PsiJavaFile) element);
allJava &= element instanceof PsiJavaFile && !JspPsiUtil.isInJspFile(element) &&
((PsiJavaFile)element).getClasses().length > 0 && !CollectHighlightsUtil.isOutsideSourceRootJavaFile((PsiJavaFile) element);
}
else {
return false;
@@ -55,6 +56,6 @@ public class JavaMoveFilesOrDirectoriesHandler extends MoveFilesOrDirectoriesHan
@Override
public void doMove(Project project, PsiElement[] elements, PsiElement targetContainer, MoveCallback callback) {
super.doMove(project, elements, targetContainer, callback); //To change body of overridden methods use File | Settings | File Templates.
super.doMove(project, elements, targetContainer, callback);
}
}
@@ -0,0 +1,83 @@
/*
* 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.refactoring.rename.naming;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.usageView.UsageInfo;
import java.util.Collection;
/**
* @author yole
*/
public class AutomaticTestRenamerFactory implements AutomaticRenamerFactory {
public boolean isApplicable(final PsiElement element) {
return element instanceof PsiClass;
}
public String getOptionName() {
return RefactoringBundle.message("rename.tests");
}
public boolean isEnabled() {
return JavaRefactoringSettings.getInstance().isToRenameTests();
}
public void setEnabled(final boolean enabled) {
JavaRefactoringSettings.getInstance().setRenameTests(enabled);
}
public AutomaticRenamer createRenamer(final PsiElement element, final String newName, final Collection<UsageInfo> usages) {
return new TestsRenamer((PsiClass)element, newName);
}
private static class TestsRenamer extends AutomaticRenamer {
public TestsRenamer(PsiClass aClass, String newClassName) {
appendTestClass(aClass, "Test");
appendTestClass(aClass, "TestCase");
suggestAllNames(aClass.getName(), newClassName);
}
private void appendTestClass(PsiClass aClass, String testSuffix) {
final Project project = aClass.getProject();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
final PsiClass psiClassTest = facade.findClass(aClass.getQualifiedName() + testSuffix, GlobalSearchScope.projectScope(project));
if (psiClassTest != null) {
myElements.add(psiClassTest);
}
}
public String getDialogTitle() {
return RefactoringBundle.message("rename.tests.title");
}
public String getDialogDescription() {
return RefactoringBundle.message("rename.tests.with.the.following.names.to");
}
public String entityName() {
return RefactoringBundle.message("entity.name.test");
}
}
}
@@ -0,0 +1,13 @@
class CSS {
static class IO{}
}
class TD {
void calculateSmth(CSS.IO io){}
}
/**
* @see TD#calculateSmth(CSS.IO)
*/
class Test {
}
@@ -0,0 +1,3 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } </style></head><body><PRE>class <b>MethodTypeParam</b>&lt;T&gt;
extends <a href="psi_element://java.lang.Object"><code>Object</code></a></PRE>
<DD><DL><DT><b>Type parameters:</b><DD><code>&lt;T&gt;</code> - type param</DD></DL></DD></body></html>
@@ -0,0 +1,6 @@
/**
* @param <T> type param
*/
class MethodTypeParam<T> {
}
@@ -0,0 +1 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } </style></head><body><small><b><a href="psi_element://A"><code>A</code></a></b></small><PRE>public static int <b>JAVADOC_ME = 23</b></PRE> The value of the field is 23.</body></html>
@@ -0,0 +1,4 @@
class A {
/** The value of the field is {@value}. */
public static int JAVADOC_ME = 23;
}
@@ -0,0 +1,2 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } </style></head><body><small><b><a href="psi_element://Idea4780"><code>Idea4780</code></a></b></small><PRE>public&nbsp;<a href="psi_element://java.lang.Object"><code>Object</code></a>&nbsp;<b>read</b>()
throws&nbsp;<a href="psi_element://java.io.IOException"><code>IOException</code></a></PRE><DD><DL><DT><b>Throws:</b><DD><a href="psi_element://java.io.EOFException"><code>EOFException</code></a> - if this source is already closed when the <code>read()</code> is called, or is closed during the <code>read()</code>. <DD><font color=red>InterruptedIOException</font> - if the reading thread is interrupted.<DD><a href="psi_element://java.io.IOException"><code>IOException</code></a> - if an I/O error occurs while reading. </DD></DL></DD></body></html>
@@ -0,0 +1,12 @@
import java.io.*;
public interface Idea4780 {
/**
* @throws IOException if an I/O error occurs while reading.
* @throws EOFException if this source is already closed when the <code>read()</code> is called,
* or is closed during the <code>read()</code>.
* @throws InterruptedIOException if the reading thread is interrupted.
*/
public Object read()
throws IOException;
}
@@ -0,0 +1 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } </style></head><body><small><b><a href="psi_element://MethodTypeParam"><code>MethodTypeParam</code></a></b></small><PRE>&lt;T&gt;&nbsp;void&nbsp;<b>foo</b>(T&nbsp;t)</PRE><DD><DL><DT><b>Type parameters:</b><DD><code>&lt;T&gt;</code> - type param</DD></DL></DD></body></html>
@@ -0,0 +1,7 @@
class MethodTypeParam {
/**
* @param <T> type param
*/
<T> void foo(T t) {
}
}
@@ -0,0 +1,4 @@
/**
* This package contains nothing but package-info.java
*/
package packageInfo;
@@ -0,0 +1,2 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } </style></head><body>
This package contains nothing but package-info.java</body></html>
@@ -0,0 +1 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } </style></head><body><small><b><a href="psi_element://A"><code>A</code></a></b></small><PRE>public static int <b>JAVADOC_ME</b></PRE> Test</body></html>
@@ -0,0 +1,4 @@
class A {
/** Test */
public static int JAVADOC_ME;
}
@@ -0,0 +1 @@
<html><head> <style type="text/css"> #error { background-color: #eeeeee; margin-bottom: 10px; } </style></head><body><small><b><a href="psi_element://A"><code>A</code></a></b></small><PRE>public static&nbsp;void&nbsp;<b>JAVADOC_ME</b>()</PRE> The value of A is 23.</body></html>
@@ -0,0 +1,6 @@
class A {
public static int A = 23;
/** The value of A is {@value #A}. */
public static void JAVADOC_ME() { }
}
@@ -1,5 +1,7 @@
import java.util.*;
class A1<T> {
A1(){}
public static void main(String[] args) {
Callable<Object> callable = new Callable<Object>() {
@@ -0,0 +1,8 @@
public class Extracted {
public Extracted() {
}
public <T> void foo(T p) {
System.out.println(p.getClass().getName());
}
}
@@ -0,0 +1,12 @@
class Test {
private final Extracted extracted = new Extracted();
public <T> void foo(T p) {
extracted.foo(p);
}
public static void main(String[] args) {
new Test().foo(10f);
}
}
@@ -0,0 +1,10 @@
class Test {
public <T> void foo(T p) {
System.out.println(p.getClass().getName());
}
public static void main(String[] args) {
new Test().foo(10f);
}
}
@@ -90,6 +90,8 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testVararg() throws Exception {doTest();}
public void testInnerClassReferenceInSignature() throws Exception {doTest();}
public void testBadReference() throws Exception{
doTest();
}
@@ -0,0 +1,79 @@
package com.intellij.codeInsight.javadoc;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.CodeInsightTestCase;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.testFramework.PsiTestUtil;
import java.io.File;
import java.io.IOException;
/**
* @author yole
*/
public class JavaDocInfoGeneratorTest extends CodeInsightTestCase {
public void testSimpleField() throws Exception {
doTestField();
}
public void testFieldValue() throws Exception {
doTestField();
}
public void testValueInMethod() throws Exception {
doTestMethod();
}
public void testIdeadev2326() throws Exception {
doTestMethod();
}
public void testMethodTypeParameter() throws Exception {
doTestMethod();
}
public void testClassTypeParameter() throws Exception {
verifyJavaDoc(getTestClass());
}
private void doTestField() throws Exception {
PsiClass psiClass = getTestClass();
PsiField field = psiClass.getFields() [0];
verifyJavaDoc(field);
}
private void doTestMethod() throws Exception {
PsiClass psiClass = getTestClass();
PsiMethod method = psiClass.getMethods() [0];
verifyJavaDoc(method);
}
private PsiClass getTestClass() throws Exception{
configureByFile("/codeInsight/javadocIG/" + getTestName(true) + ".java");
return ((PsiJavaFile)myFile).getClasses() [0];
}
private void verifyJavaDoc(final PsiElement field) throws IOException {
final File htmlPath = new File(JavaTestUtil.getJavaTestDataPath() + "/codeInsight/javadocIG/" + getTestName(true) + ".html");
String htmlText = new String(FileUtil.loadFileText(htmlPath));
String docInfo = new JavaDocInfoGenerator(getProject(), field).generateDocInfo(null);
assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), StringUtil.convertLineSeparators(docInfo.trim()));
}
public void testPackageInfo() throws Exception {
final String path = JavaTestUtil.getJavaTestDataPath() + "/codeInsight/javadocIG/";
final String packageInfo = path + getTestName(true);
PsiTestUtil.createTestProjectStructure(myProject, myModule, path, myFilesToDelete);
final String info =
new JavaDocInfoGenerator(getProject(), JavaPsiFacade.getInstance(getProject()).findPackage(getTestName(true))).generateDocInfo(null);
String htmlText = new String(FileUtil.loadFileText(new File(packageInfo + File.separator + "packageInfo.html")));
assertEquals(StringUtil.convertLineSeparators(htmlText.trim()), StringUtil.convertLineSeparators(info.trim()));
}
@Override
protected String getTestDataPath() {
return JavaTestUtil.getJavaTestDataPath();
}
}
@@ -2,7 +2,6 @@ package com.intellij.psi.formatter;
import com.intellij.JavaTestUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
@@ -35,7 +34,6 @@ public class JavaFormatterTest extends LightIdeaTestCase {
doTest("SCR915.java", "SCR915_after.java");
}
public void testForEach() throws Exception {
doTest("ForEach.java", "ForEach_after.java");
}
@@ -208,6 +206,35 @@ public class JavaFormatterTest extends LightIdeaTestCase {
doTest();
}
public void testNestedMethodsIndentation() throws Exception {
// Inspired by IDEA-43962
getSettings().getIndentOptions(StdFileTypes.JAVA).CONTINUATION_INDENT_SIZE = 4;
doMethodTest(
"BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
".add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE)))))))));",
"BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE\n" +
" .add(BigDecimal.ONE)))))))));"
);
}
public void testSwitch() throws Exception {
doTest();
}
@@ -2893,22 +2920,26 @@ public class JavaFormatterTest extends LightIdeaTestCase {
getSettings().ARRAY_INITIALIZER_WRAP = CodeStyleSettings.WRAP_ALWAYS;
getSettings().ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE = true;
getSettings().ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE = true;
doTextTest("public @interface Ann\n" +
doTextTest(
"public @interface Ann\n" +
"{\n" +
"int[] x = { 1, 2 };\n" +
"\n" +
"Mode[] modes () default { @Mode(value = 1), @Mode(value = 2) };\n" +
"}", "public @interface Ann {\n" +
" int[] x = {\n" +
" 1,\n" +
" 2\n" +
" };\n" +
"\n" +
" Mode[] modes() default {\n" +
" @Mode(value = 1),\n" +
" @Mode(value = 2)\n" +
" };\n" +
"}");
"}",
"public @interface Ann {\n" +
" int[] x = {\n" +
" 1,\n" +
" 2\n" +
" };\n" +
"\n" +
" Mode[] modes() default {\n" +
" @Mode(value = 1),\n" +
" @Mode(value = 2)\n" +
" };\n" +
"}"
);
}
private void doMethodTest(final String before, final String after) throws Exception {
@@ -227,6 +227,10 @@ public class ExtractClassTest extends MultiFileTestCase{
doTestField(null);
}
public void testMethodTypeParameters() throws Exception {
doTestMethod();
}
public void testPublicVisibility() throws Exception {
doTest(new PerformAction() {
public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception {
@@ -78,4 +78,8 @@ public abstract class LookupElement extends UserDataHolderBase {
//noinspection unchecked
return aClass.isInstance(this) ? (T) this : null;
}
public boolean isCaseSensitive() {
return true;
}
}
@@ -112,6 +112,10 @@ public abstract class LookupElementDecorator<T extends LookupElement> extends Lo
final T t = super.as(aClass);
return t == null ? myDelegate.as(aClass) : t;
}
public boolean isCaseSensitive() {
return myDelegate.isCaseSensitive();
}
private static class InsertingDecorator<T extends LookupElement> extends LookupElementDecorator<T> {
private final InsertHandler<? super LookupElementDecorator<T>> myInsertHandler;
@@ -15,8 +15,6 @@
*/
package com.intellij.formatting;
import com.intellij.openapi.diagnostic.Logger;
/**
* The wrap setting for a formatting model block. Indicates the conditions under which a line break
* is inserted before the block when formatting, if the block extends beyond the
@@ -34,15 +32,46 @@ public abstract class Wrap {
private static WrapFactory myFactory;
/**
* @deprecated use {@link WrapType#ALWAYS} instead
*/
@Deprecated
public static WrapType ALWAYS = WrapType.ALWAYS;
/**
* @deprecated use {@link WrapType#NORMAL} instead
*/
@Deprecated
public static WrapType NORMAL = WrapType.NORMAL;
/**
* @deprecated use {@link WrapType#NONE} instead
*/
@Deprecated
public static WrapType NONE = WrapType.NONE;
/**
* @deprecated use {@link WrapType#CHOP_DOWN_IF_LONG} instead
*/
@SuppressWarnings({"UnusedDeclaration"})
@Deprecated
public static WrapType CHOP_DOWN_IF_LONG = WrapType.CHOP_DOWN_IF_LONG;
static void setFactory(WrapFactory factory) {
myFactory = factory;
}
/**
* Creates a block wrap setting of the legacy representation of specified wrap type (see {@link WrapType#getLegacyRepresentation()}).
*
* @param type the type of the wrap setting.
* @param wrapFirstElement if <code>true</code>, the first element in a sequence of elements of the same type is also wrapped.
* @return the wrap setting instance.
*/
public static Wrap createWrap(final int type, final boolean wrapFirstElement) {
return myFactory.createWrap(WrapType.byLegacyRepresentation(type), wrapFirstElement);
}
/**
* Creates a block wrap setting of the specified type.
*
@@ -15,6 +15,11 @@
*/
package com.intellij.formatting;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import java.util.HashMap;
import java.util.Map;
/**
* Defines possible types of a wrap.
*
@@ -23,29 +28,69 @@ package com.intellij.formatting;
*/
public enum WrapType {
/**
* A line break is always inserted before the start of the element.
* This corresponds to the "Wrap always" setting in Global Code Style | Wrapping.
*/
ALWAYS,
ALWAYS(CodeStyleSettings.WRAP_ALWAYS),
/**
* A line break is inserted before the start of the element if the right edge
* of the element goes beyond the specified wrap margin.
* This corresponds to the "Wrap if long" setting in Global Code Style | Wrapping.
*/
NORMAL,
NORMAL(CodeStyleSettings.WRAP_AS_NEEDED),
/**
* A line break is never inserted before the start of the element.
* This corresponds to the "Do not wrap" setting in Global Code Style | Wrapping.
*/
NONE,
NONE(CodeStyleSettings.DO_NOT_WRAP),
/**
* A line break is inserted before the start of the element if it is a part
* of list of elements of the same type and at least one of the elements was wrapped.
* This corresponds to the "Chop down if long" setting in Global Code Style | Wrapping.
*/
CHOP_DOWN_IF_LONG
CHOP_DOWN_IF_LONG(CodeStyleSettings.WRAP_ON_EVERY_ITEM);
private static final Map<Integer, WrapType> LEGACY_MAPPINGS = new HashMap<Integer, WrapType>();
static {
for (WrapType wrapType : values()) {
LEGACY_MAPPINGS.put(wrapType.getLegacyRepresentation(), wrapType);
}
}
private final int myLegacyRepresentation;
WrapType(int legacyRepresentation) {
myLegacyRepresentation = legacyRepresentation;
}
/**
* Allows to retrieve wrap type by it's legacy non-type-safe representation (see {@link #getLegacyRepresentation()}).
*
* @param value legacy representation of the target wrap type
* @return wrap type which {@link #getLegacyRepresentation() legacyRepresentation} is equal to the given value if any;
* {@link #CHOP_DOWN_IF_LONG} otherwise
*/
public static WrapType byLegacyRepresentation(int value) {
WrapType result = LEGACY_MAPPINGS.get(value);
return result == null ? CHOP_DOWN_IF_LONG : result;
}
/**
* Wrapping types were used as a primitive constants during this enum introduction (e.g. {@link CodeStyleSettings#DO_NOT_WRAP} etc).
* <p/>
* It's possible to map that legacy representation to the object-level enum member via {@link #byLegacyRepresentation(int)}.
* <p/>
* Current getter exposes legacy value associated with the current object-level wrap type representation.
*
* @return legacy representation of the current wrap type
*/
public int getLegacyRepresentation() {
return myLegacyRepresentation;
}
}
@@ -17,6 +17,7 @@ package com.intellij.psi;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.KeyedExtensionCollector;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -37,7 +38,7 @@ public class WeighingService {
@NotNull
public static <T,Loc> WeighingComparable<T,Loc> weigh(Key<? extends Weigher<T,Loc>> key, T element, Loc location) {
final List<Weigher> weighers = COLLECTOR.forKey(key);
return new WeighingComparable<T,Loc>(element, location, weighers.toArray(new Weigher[weighers.size()]));
return new WeighingComparable<T,Loc>(element, location, ContainerUtil.toArray(weighers, new Weigher[weighers.size()]));
}
}
@@ -30,6 +30,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,7 +43,7 @@ import java.util.Set;
* @author peter
*/
public class FileContentUtil {
public static final String FORCE_RELOAD_REQUESTOR = "FileContentUtil.saveOrReload";
@NonNls public static final String FORCE_RELOAD_REQUESTOR = "FileContentUtil.saveOrReload";
private FileContentUtil() {
}
@@ -67,23 +68,23 @@ public class FileContentUtil {
}
public static void reparseFiles(@NotNull final Project project, @NotNull final Collection<VirtualFile> files, boolean includeOpenFiles) {
final Set<VFilePropertyChangeEvent> list = new THashSet<VFilePropertyChangeEvent>();
final Set<VFilePropertyChangeEvent> events = new THashSet<VFilePropertyChangeEvent>();
for (VirtualFile file : files) {
saveOrReload(file, list);
saveOrReload(file, events);
}
if (includeOpenFiles) {
for (VirtualFile open : FileEditorManager.getInstance(project).getOpenFiles()) {
if (!files.contains(open)) {
saveOrReload(open, list);
saveOrReload(open, events);
}
}
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
ApplicationManager.getApplication().getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES)
.before(new ArrayList<VFileEvent>(list));
.before(new ArrayList<VFileEvent>(events));
ApplicationManager.getApplication().getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES)
.after(new ArrayList<VFileEvent>(list));
.after(new ArrayList<VFileEvent>(events));
}
});
}
@@ -7,8 +7,6 @@ package com.intellij.codeInsight.completion.impl;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.PrefixMatcher;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.codeStyle.NameUtil;
import com.intellij.util.containers.hash.LinkedHashMap;
@@ -62,12 +60,7 @@ public class CamelHumpMatcher extends PrefixMatcher {
public boolean prefixMatches(@NotNull final LookupElement element) {
final LookupItem item = element.as(LookupItem.class); //must die, use LookupElementBuilder or CompletionResultSet.caseInsensitive
final LookupElementBuilder builder = element.as(LookupElementBuilder.class);
boolean itemCaseInsensitive = item != null && Boolean.TRUE.equals(item.getAttribute(LookupItem.CASE_INSENSITIVE)) ||
builder != null && !builder.isCaseSensitive();
return prefixMatchersInternal(element, itemCaseInsensitive);
return prefixMatchersInternal(element, !element.isCaseSensitive());
}
private boolean prefixMatchersInternal(final LookupElement element, final boolean itemCaseInsensitive) {
@@ -316,6 +316,12 @@ public class DocumentationManager {
component.setHint(hint);
if (myEditor == null) {
// subsequent invocation of javadoc popup from completion will have myEditor == null because of cancel invoked,
// so reevaluate the editor for proper popup placement
Lookup lookup = LookupManager.getInstance(myProject).getActiveLookup();
myEditor = lookup != null ? lookup.getEditor() : null;
}
fetchDocInfo(getDefaultCollector(element, originalElement), component);
myDocInfoHintRef = new WeakReference<JBPopup>(hint);
@@ -359,4 +359,16 @@ public class LookupItem<T> extends MutableLookupElement<T> implements Comparable
myAttributes.putAll(item.myAttributes);
}
@Override
public boolean isCaseSensitive() {
return !Boolean.TRUE.equals(getAttribute(CASE_INSENSITIVE));
}
public static @Nullable LookupItem from(LookupElement lookupElement) {
if (lookupElement instanceof LookupElementDecorator) {
lookupElement = ((LookupElementDecorator)lookupElement).getDelegate();
}
if (lookupElement instanceof LookupItem) return (LookupItem)lookupElement;
return null;
}
}
@@ -125,7 +125,7 @@ public abstract class AbstractBlockWrapper {
}
/**
* Calculates indent for the given block and target start offset according to the given idnent options.
* Calculates indent for the given block and target start offset according to the given indent options.
*
* @param options indent options to use
* @param block target wrapped block
@@ -255,18 +255,13 @@ public abstract class AbstractBlockWrapper {
return indent.add(getWhiteSpace());
}
else {
ArrayList<IndentData> ignored = new ArrayList<IndentData>();
IndentData offsetFromParent = myParent.getChildOffset(this, indentOption, -1);
IndentData result = indent.add(offsetFromParent);
if (!ignored.isEmpty()) {
result = result.add(ignored.get(ignored.size() - 1));
}
return result;
return indent.add(offsetFromParent);
}
}
private IndentData getIndent(final CodeStyleSettings.IndentOptions options, final int index, IndentImpl indent) {
private static IndentData getIndent(final CodeStyleSettings.IndentOptions options, final int index, IndentImpl indent) {
if (indent.getType() == IndentImpl.Type.CONTINUATION) {
return new IndentData(options.CONTINUATION_INDENT_SIZE);
}
@@ -292,7 +287,7 @@ public abstract class AbstractBlockWrapper {
* value is defined (not <code>null</code>).
* <p/>
* This property is used later during
* {@link LeafBlockWrapper#calculateOffset(CodeStyleSettings.IndentOptions) leaf block offset calculation}.
* {@link LeafBlockWrapper#calculateOffset(CodeStyleSettings.IndentOptions)} leaf block offset calculation}.
*
* @param indentFromParent indent value to apply
*/
@@ -340,4 +335,9 @@ public abstract class AbstractBlockWrapper {
myParent = null;
myWhiteSpace = null;
}
@Override
public String toString() {
return getClass().getName() + "(" + myStart + "-" + myEnd + ")";
}
}
@@ -629,9 +629,9 @@ class FormatProcessor {
}
/**
* Tries to get align-implied indent of the line that contains current block.
* Tries to get align-implied indent of the current block.
*
* @return indent of the line that contains current block if any; <code>null</code> otherwise
* @return indent of the current block if any; <code>null</code> otherwise
*/
@Nullable
private IndentData getAlignOffset() {
@@ -279,8 +279,7 @@ public class FormatterImpl extends FormatterEx
{
boolean wsContainsCaret = whiteSpace.getStartOffset() <= offset && offset < whiteSpace.getEndOffset();
final CharSequence text = getCharSequence(documentModel);
int lineStartOffset = getLineStartOffset(offset, whiteSpace, text, documentModel);
int lineStartOffset = getLineStartOffset(offset, whiteSpace, documentModel);
final IndentInfo indent = calcIndent(offset, documentModel, processor, whiteSpace);
@@ -325,7 +324,7 @@ public class FormatterImpl extends FormatterEx
final WhiteSpace whiteSpace = blockAfterOffset.getWhiteSpace();
final IndentInfo indent = calcIndent(offset, documentModel, processor, whiteSpace);
return indent.generateNewWhiteSpace(indentOptions).toString();
return indent.generateNewWhiteSpace(indentOptions);
}
return null;
}
@@ -355,10 +354,10 @@ public class FormatterImpl extends FormatterEx
private static int getLineStartOffset(final int offset,
final WhiteSpace whiteSpace,
final CharSequence text,
final FormattingDocumentModel documentModel) {
int lineStartOffset = offset;
CharSequence text = getCharSequence(documentModel);
lineStartOffset = CharArrayUtil.shiftBackwardUntil(text, lineStartOffset, " \t\n");
if (lineStartOffset > whiteSpace.getStartOffset()) {
if (lineStartOffset >= text.length()) lineStartOffset = text.length() - 1;
@@ -572,10 +571,6 @@ public class FormatterImpl extends FormatterEx
return myContinutationWithoutFirstIndent;
}
public static int getLineFeedsToModified(final FormattingDocumentModel model, final int offset, final int startOffset) {
return model.getLineNumber(offset) - model.getLineNumber(startOffset);
}
private final Object DISABLING_LOCK = new Object();
public boolean isDisabled() {
@@ -20,8 +20,6 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
class LeafBlockWrapper extends AbstractBlockWrapper {
private static final int CONTAIN_LINE_FEEDS = 4;
private static final int READ_ONLY = 8;
@@ -149,12 +147,7 @@ class LeafBlockWrapper extends AbstractBlockWrapper {
}
}
ArrayList<IndentData> ignored = new ArrayList<IndentData>();
IndentData result = myParent.getChildOffset(this, options, this.getStartOffset());
if (!ignored.isEmpty()) {
result = result.add(ignored.get(ignored.size() - 1));
}
return result;
return myParent.getChildOffset(this, options, this.getStartOffset());
}
public void setSpaceProperty(final SpacingImpl currentSpaceProperty) {
@@ -191,8 +184,4 @@ class LeafBlockWrapper extends AbstractBlockWrapper {
return new TextRange(myStart, myEnd);
}
@Override
public String toString() {
return "LeafBlockWrapper(" + myStart + "-" + myEnd + ")";
}
}
@@ -33,8 +33,10 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.IconLoader;
import com.intellij.pom.Navigatable;
import com.intellij.ui.*;
import com.intellij.ui.content.Content;
import com.intellij.ui.treeStructure.Tree;
@@ -352,6 +354,7 @@ public class ModulesDependenciesPanel extends JPanel implements ModuleRootListen
group.add(actionManager.createExpandAllAction(treeExpander, tree));
}
group.add(actionManager.createCollapseAllAction(treeExpander, tree));
group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE));
group.add(ActionManager.getInstance().getAction(IdeActions.MODULE_SETTINGS));
appendDependenciesAction(group);
return group;
@@ -406,7 +409,7 @@ public class ModulesDependenciesPanel extends JPanel implements ModuleRootListen
TreeUtil.selectFirstNode(myLeftTree);
}
private static class MyUserObject{
private static class MyUserObject implements Navigatable{
private boolean myInCycle;
private final Module myModule;
@@ -438,6 +441,18 @@ public class ModulesDependenciesPanel extends JPanel implements ModuleRootListen
public String toString() {
return myModule.getName();
}
public void navigate(boolean requestFocus) {
ProjectSettingsService.getInstance(myModule.getProject()).openModuleSettings(myModule);
}
public boolean canNavigate() {
return myModule != null && !myModule.isDisposed();
}
public boolean canNavigateToSource() {
return false;
}
}
private static class MyTreePanel extends JPanel implements DataProvider{
@@ -466,6 +481,15 @@ public class ModulesDependenciesPanel extends JPanel implements ModuleRootListen
if (PlatformDataKeys.HELP_ID.is(dataId)) {
return ourHelpID;
}
if (PlatformDataKeys.NAVIGATABLE.is(dataId)) {
final TreePath selectionPath = myTree.getLeadSelectionPath();
if (selectionPath != null && selectionPath.getLastPathComponent() instanceof DefaultMutableTreeNode){
DefaultMutableTreeNode node = (DefaultMutableTreeNode)selectionPath.getLastPathComponent();
if (node.getUserObject() instanceof MyUserObject){
return node.getUserObject();
}
}
}
return null;
}
}
@@ -18,6 +18,7 @@ package com.intellij.packageDependencies.ui;
import com.intellij.analysis.AnalysisScopeBundle;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiFile;
@@ -40,6 +41,21 @@ public class ModuleNode extends PackageDependenciesNode {
}
}
@Override
public boolean canNavigate() {
return myModule != null && !myModule.isDisposed();
}
@Override
public boolean canNavigateToSource() {
return false;
}
@Override
public void navigate(boolean focus) {
ProjectSettingsService.getInstance(myModule.getProject()).openModuleSettings(myModule);
}
public Icon getOpenIcon() {
return myModule == null ? null : myModule.getModuleType().getNodeIcon(true);
}
@@ -19,10 +19,12 @@ import com.intellij.lang.ASTFactory;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.TokenType;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
@@ -248,4 +250,22 @@ public class FormatterUtil {
return true;
}
public static boolean isPrecededBy(ASTNode node, IElementType eType) {
ASTNode prevNode = node.getTreePrev();
while (prevNode != null && prevNode.getPsi() instanceof PsiWhiteSpace) {
prevNode = prevNode.getTreePrev();
}
if (prevNode == null) return false;
return prevNode.getElementType() == eType;
}
public static boolean isPrecededBy(ASTNode node, TokenSet tokens) {
ASTNode prevNode = node.getTreePrev();
while (prevNode != null && prevNode.getPsi() instanceof PsiWhiteSpace) {
prevNode = prevNode.getTreePrev();
}
if (prevNode == null) return false;
return tokens.contains(prevNode.getElementType());
}
}
@@ -0,0 +1,72 @@
/*
* 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.psi.formatter;
import com.intellij.formatting.Wrap;
import com.intellij.formatting.WrapType;
import com.intellij.lang.ASTNode;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.tree.IElementType;
/**
* Misc. code wrapping functions
* @author rvishnyakov
*/
public class WrappingUtil {
private WrappingUtil() {
}
public static boolean shouldWrap(int setting) {
return setting != CodeStyleSettings.DO_NOT_WRAP;
}
public static Wrap createWrap(int setting) {
return Wrap.createWrap(getWrapType(setting), true);
}
public static WrapType getWrapType(int setting) {
switch (setting) {
case CodeStyleSettings.WRAP_ALWAYS:
return WrapType.ALWAYS;
case CodeStyleSettings.WRAP_AS_NEEDED:
return WrapType.NORMAL;
case CodeStyleSettings.DO_NOT_WRAP:
return WrapType.NONE;
default:
return WrapType.CHOP_DOWN_IF_LONG;
}
}
public static WrapType getArrayInitializerWrapType(CodeStyleSettings settings,
ASTNode node,
IElementType lBraceType,
IElementType rBraceType) {
WrapType wrapType = WrapType.NONE;
if (shouldWrap(settings.ARRAY_INITIALIZER_WRAP)) {
if (node.getElementType() == rBraceType) {
wrapType = settings.ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE ? Wrap.ALWAYS : Wrap.NONE;
}
else if (FormatterUtil.isPrecededBy(node, lBraceType)) {
wrapType = settings.ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE ? Wrap.ALWAYS : Wrap.NONE;
}
else {
wrapType = WrappingUtil.getWrapType(settings.ARRAY_INITIALIZER_WRAP);
}
}
return wrapType;
}
}
@@ -67,16 +67,33 @@ public class ChangeList {
myChangeSetDepth++;
if (myChangeSetDepth > 1) return;
doBeginChangeSet();
}
private void doBeginChangeSet() {
myCurrentChangeSet = new ChangeSet(myStorage.nextId(), Clock.getCurrentTimestamp());
myCurrentBlock.add(myCurrentChangeSet);
}
public synchronized boolean forceBeginChangeSet() {
boolean split = myChangeSetDepth > 0;
if (split) doEndChangeSet(null);
myChangeSetDepth++;
doBeginChangeSet();
return split;
}
public synchronized boolean endChangeSet(String name) {
assert myChangeSetDepth > 0;
myChangeSetDepth--;
if (myChangeSetDepth > 0) return false;
return doEndChangeSet(name);
}
private boolean doEndChangeSet(String name) {
if (myCurrentChangeSet.getChanges().isEmpty()) {
myCurrentBlock.removeLast();
return false;
@@ -144,7 +161,7 @@ public class ChangeList {
}
private void flushChanges(boolean force) {
if (myChangeSetDepth > 0) return;
if (myChangeSetDepth > 0) return;
if (myCurrentBlock.shouldFlush(force) || flushEveryChangeSetInTests()) {
myStorage.writeNextBlock(myCurrentBlock);
myCurrentBlock = myStorage.createNewBlock();
@@ -140,7 +140,7 @@ public class ChangeListStorageImpl implements ChangeListStorage {
}
public synchronized List<ChangeSetBlock> purge(long period, int intervalBetweenActivities) {
List<ChangeSetBlock> result = new ArrayList<ChangeSetBlock>();
List<ChangeSetBlock> result = new ArrayList<ChangeSetBlock>(); // todo : do not collect changesets
int each = findFirstObsoleteBlock(period, intervalBetweenActivities);
try {
while(each != 0) {
@@ -155,7 +155,6 @@ public class ChangeListStorageImpl implements ChangeListStorage {
return result;
}
private int findFirstObsoleteBlock(long period, int intervalBetweenActivities) {
long prevTimestamp = 0;
long length = 0;
@@ -178,8 +177,7 @@ public class ChangeListStorageImpl implements ChangeListStorage {
return 0;
}
public void flush() {
public synchronized void flush() {
myStorage.flushSome();
}
}
@@ -23,7 +23,7 @@ import java.io.File;
import java.io.IOException;
public class LinkedRecordsTable extends AbstractRecordsTable {
private static final int VERSION = 3;
private static final int VERSION = 4;
private static final int ID_COUNTER_OFFSET = DEFAULT_HEADER_SIZE;
private static final int FIRST_RECORD_OFFSET = ID_COUNTER_OFFSET + 8;
@@ -62,6 +62,13 @@ public class LinkedRecordsTable extends AbstractRecordsTable {
return ZEROS;
}
@Override
protected void clearDeletedRecord(int record) {
setTimestamp(record, 0);
setNextRecord(record, 0);
setPrevRecord(record, 0);
}
public void setFSTimestamp(long timestamp) {
markDirty();
myStorage.putLong(FS_TIMESTAMP_OFFSET, timestamp);
@@ -77,7 +84,6 @@ public class LinkedRecordsTable extends AbstractRecordsTable {
}
public int getFirstRecord() {
markDirty();
return myStorage.getInt(FIRST_RECORD_OFFSET);
}
@@ -87,7 +93,6 @@ public class LinkedRecordsTable extends AbstractRecordsTable {
}
public int getLastRecord() {
markDirty();
return myStorage.getInt(LAST_RECORD_OFFSET);
}
@@ -55,6 +55,12 @@ public class LinkedStorage extends AbstractStorage {
}
}
public int getFirstRecord() {
synchronized (myLock) {
return ((LinkedRecordsTable)myRecordsTable).getFirstRecord();
}
}
public int getLastRecord() {
synchronized (myLock) {
return ((LinkedRecordsTable)myRecordsTable).getLastRecord();
@@ -67,6 +73,12 @@ public class LinkedStorage extends AbstractStorage {
}
}
public int getNextRecord(int record) {
synchronized (myLock) {
return ((LinkedRecordsTable)myRecordsTable).getNextRecord(record);
}
}
public long getTimestamp(int record) {
synchronized (myLock) {
return ((LinkedRecordsTable)myRecordsTable).getTimestamp(record);
@@ -46,6 +46,12 @@ public class LocalHistoryFacade {
myChangeList.beginChangeSet();
}
public void forceBeginChangeSet() {
if (myChangeList.forceBeginChangeSet()) {
fireChangeSetFinished();
}
}
public void endChangeSet(String name) {
if (myChangeList.endChangeSet(name)) {
fireChangeSetFinished();
@@ -52,8 +52,8 @@ public class StreamUtil {
}
public static Change readChange(DataInput in) throws IOException {
switch (in.readInt()) {
case 0:
int type = in.readInt();
switch (type) {
case 1:
return new CreateFileChange(in);
case 2:
@@ -73,14 +73,13 @@ public class StreamUtil {
case 9:
return new PutSystemLabelChange(in);
}
throw new IOException();
throw new IOException("unexpected change type: " + type);
}
public static void writeChange(DataOutput out, Change change) throws IOException {
int id = -1;
Class c = change.getClass();
if (c.equals(ChangeSet.class)) id = 0;
if (c.equals(CreateFileChange.class)) id = 1;
if (c.equals(CreateDirectoryChange.class)) id = 2;
if (c.equals(ContentChange.class)) id = 3;
@@ -91,7 +90,7 @@ public class StreamUtil {
if (c.equals(PutLabelChange.class)) id = 8;
if (c.equals(PutSystemLabelChange.class)) id = 9;
assert id != -1;
if (id == -1) throw new IOException("unexpected change type: " + c);
out.writeInt(id);
change.write(out);
@@ -30,9 +30,7 @@ public class LocalHistoryEventDispatcher extends VirtualFileAdapter implements V
private static final Key<Boolean> WAS_VERSIONED_KEY = Key.create(LocalHistoryEventDispatcher.class.getSimpleName() + ".WAS_VERSIONED_KEY");
private final LocalHistoryFacade myVcs;
private final IdeaGateway myGateway;
private int myChangeSetDepth = 0;
public LocalHistoryEventDispatcher(LocalHistoryFacade vcs, IdeaGateway gw) {
myVcs = vcs;
@@ -64,41 +62,22 @@ public class LocalHistoryEventDispatcher extends VirtualFileAdapter implements V
public void undoTransparentActionFinished() {
}
public synchronized void startAction() {
// save document in current or new changeset and close it
if (myChangeSetDepth == 0) {
myVcs.beginChangeSet();
}
public void startAction() {
myGateway.registerUnsavedDocuments(myVcs);
myVcs.endChangeSet(null);
// restore changeset if there were before saving the documents
if (myChangeSetDepth > 0) {
myVcs.beginChangeSet();
}
beginChangeSet();
myVcs.forceBeginChangeSet();
}
public synchronized void finishAction(String name) {
public void finishAction(String name) {
myGateway.registerUnsavedDocuments(myVcs);
endChangeSet(name);
}
private synchronized void beginChangeSet() {
myChangeSetDepth++;
if (myChangeSetDepth == 1) {
myVcs.beginChangeSet();
}
private void beginChangeSet() {
myVcs.beginChangeSet();
}
private synchronized void endChangeSet(String name) {
LocalHistoryLog.LOG.assertTrue(myChangeSetDepth > 0, "changeset depth is invalid");
myChangeSetDepth--;
if (myChangeSetDepth == 0) {
myVcs.endChangeSet(name);
}
private void endChangeSet(String name) {
myVcs.endChangeSet(name);
}
@Override
@@ -113,7 +92,7 @@ public class LocalHistoryEventDispatcher extends VirtualFileAdapter implements V
myVcs.created(f.getPath(), f.isDirectory());
}
if (f.isDirectory()) {
for (VirtualFile each : ((NewVirtualFile)f).getChildren()) {
for (VirtualFile each : ((NewVirtualFile)f).iterInDbChildren()) {
createRecursively(each);
}
}
@@ -81,7 +81,6 @@ public class DirectoryHistoryDialog extends HistoryDialog<DirectoryHistoryDialog
p.add(myToolBar.getComponent(), BorderLayout.NORTH);
p.add(myChangesTree, BorderLayout.CENTER);
p.add(new DiffStatusBar(DiffStatusBar.DEFAULT_TYPES), BorderLayout.SOUTH);
return p;
}
@@ -115,6 +115,28 @@ public class ChangeListTest extends ChangeListTestCase {
assertEquals(array(c1, c2), cc.get(0).getChanges());
}
@Test
public void testForcesBegin() throws Exception {
facade.beginChangeSet();
add(facade, createFile(r, "f1"));
facade.beginChangeSet();
add(facade, createFile(r, "f2"));
facade.forceBeginChangeSet();
add(facade, createFile(r, "f3"));
facade.endChangeSet("a");
add(facade, createFile(r, "f4"));
facade.endChangeSet("b");
add(facade, createFile(r, "f5"));
facade.endChangeSet("c");
List<ChangeSet> cc = facade.getChangeListInTests().getChangesInTests();
assertEquals(2, cc.size());
assertEquals("c", cc.get(0).getName());
assertEquals(3, cc.get(0).getChanges().size());
assertEquals(null, cc.get(1).getName());
assertEquals(2, cc.get(1).getChanges().size());
}
@Test
public void testChangeSetTimestamp() {
setCurrentTimestamp(123);
@@ -0,0 +1,147 @@
/*
* 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.historyIntegrTests;
import com.intellij.history.core.LinkedStorage;
import com.intellij.util.io.storage.AbstractStorage;
import java.io.DataInputStream;
import java.io.IOException;
public class LinkedStorageTest extends IntegrationTestCase {
private LinkedStorage myStorage;
@Override
public void setUp() throws Exception {
super.setUp();
myStorage = new LinkedStorage(myRoot.getPath() + "/storage");
}
@Override
protected void tearDown() throws Exception {
myStorage.dispose();
super.tearDown();
}
public void testBasic() throws Exception {
assertFirstAndLast(0, 0);
int r1 = createRecord();
int r2 = createRecord();
assertFirstAndLast(r1, r2);
assertRecord(r2, r1, 0);
assertRecord(r1, 0, r2);
}
public void testDeletion() throws Exception {
int r1 = createRecord();
int r2 = createRecord();
int r3 = createRecord();
assertFirstAndLast(r1, r3);
assertRecord(r3, r2, 0);
assertRecord(r2, r1, r3);
assertRecord(r1, 0, r2);
myStorage.deleteRecord(r2);
assertFirstAndLast(r1, r3);
assertRecord(r3, r1, 0);
assertRecord(r1, 0, r3);
myStorage.deleteRecord(r3);
assertFirstAndLast(r1, r1);
assertRecord(r1, 0, 0);
int r4 = createRecord();
assertFirstAndLast(r1, r4);
assertRecord(r4, r1, 0);
assertRecord(r1, 0, r4);
myStorage.deleteRecord(r1);
assertFirstAndLast(r4, r4);
assertRecord(r4, 0, 0);
myStorage.deleteRecord(r4);
assertFirstAndLast(0, 0);
}
public void testReopening() throws Exception {
int r1 = createRecord();
int r2 = createRecord();
int r3 = createRecord();
myStorage.deleteRecord(r2);
myStorage.dispose();
myStorage = new LinkedStorage(myRoot.getPath() + "/storage");
assertFirstAndLast(r1, r3);
assertRecord(r3, r1, 0);
assertRecord(r1, 0, r3);
myStorage.deleteRecord(r1);
myStorage.dispose();
myStorage = new LinkedStorage(myRoot.getPath() + "/storage");
assertFirstAndLast(r3, r3);
assertRecord(r3, 0, 0);
int r4 = createRecord();
myStorage.dispose();
myStorage = new LinkedStorage(myRoot.getPath() + "/storage");
assertFirstAndLast(r3, r4);
assertRecord(r4, r3, 0);
assertRecord(r3, 0, r4);
}
private int createRecord() throws IOException {
int r = myStorage.createNextRecord();
AbstractStorage.StorageDataOutput s = myStorage.writeStream(r);
for (int i = 0; i < 1000; i++) {
s.writeInt(r);
}
s.close();
return r;
}
private void assertFirstAndLast(int first, int last) {
assertEquals(first, myStorage.getFirstRecord());
assertEquals(last, myStorage.getLastRecord());
}
private void assertRecord(int id, int prev, int next) throws IOException {
assertEquals(prev, myStorage.getPrevRecord(id));
assertEquals(next, myStorage.getNextRecord(id));
DataInputStream s = myStorage.readStream(id);
try {
for (int i = 0; i < 1000; i++) {
assertEquals(id, s.readInt());
}
}
finally {
s.close();
}
}
}
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Map;
/**
* @author oleg
* @author Roman.Chernyatchik, oleg
*/
public interface CommandLineArgumentsProvider {
/**
@@ -24,6 +24,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.encoding.EncodingManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFilePropertyChangeEvent;
import com.intellij.util.Icons;
import org.jetbrains.annotations.NonNls;
@@ -36,6 +37,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
/**
* Represents a file in <code>{@link VirtualFileSystem}</code>. A particular file is represented by the same
@@ -451,7 +453,10 @@ public abstract class VirtualFile extends UserDataHolderBase implements Modifica
if (isValid() && !application.isDisposed()) {
application.runWriteAction(new Runnable(){
public void run() {
application.getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES).after(Collections.singletonList(new VFilePropertyChangeEvent(this, VirtualFile.this, PROP_ENCODING, old, charset, false)));
List<VFilePropertyChangeEvent> events = Collections.singletonList(new VFilePropertyChangeEvent(this, VirtualFile.this, PROP_ENCODING, old, charset, false));
BulkFileListener listener = application.getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES);
listener.before(events);
listener.after(events);
}
});
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.ui.FixedSizeButton;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.CharFilter;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -50,6 +51,11 @@ public class GuiUtils {
private static final Insets paddingInsideDialog = new Insets(5, 5, 5, 5);
public static final int lengthForFileField = 25;
private static final CharFilter NOT_MNEMONIC_CHAR_FILTER = new CharFilter() {
public boolean accept(char ch) {
return ch != '&' && ch != UIUtil.MNEMONIC;
}
};
public static JPanel constructFieldWithBrowseButton(JComponent aComponent, ActionListener aActionListener) {
return constructFieldWithBrowseButton(aComponent, aActionListener, 0);
@@ -187,7 +193,7 @@ public class GuiUtils {
}
public static String getTextWithoutMnemonicEscaping(String text) {
return text.replaceAll("&", "");
return StringUtil.strip(text, NOT_MNEMONIC_CHAR_FILTER);
}
public static char getDisplayedMnemonic(String text) {
@@ -108,7 +108,6 @@ public class ColorProgressBar extends JComponent {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (myFraction == 0) return;
Graphics2D g2 = (Graphics2D)g;
Object oldAntialiasing = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
@@ -110,6 +110,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
connection.subscribe(StateStorage.STORAGE_TOPIC, new StateStorage.Listener() {
public void storageFileChanged(final VirtualFileEvent event, @NotNull final StateStorage storage) {
VirtualFile file = event.getFile();
LOG.info("[RELOAD] Storage file changed: " + file.getPath());
if (!file.isDirectory() && !(event.getRequestor() instanceof StateStorage.SaveSession)) {
saveChangedProjectFile(file, null, storage);
}
@@ -535,6 +536,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
}
private void askToReloadProjectIfConfigFilesChangedExternally() {
LOG.info("[RELOAD] myReloadBlockCount = " + myReloadBlockCount.get());
if (myReloadBlockCount.get() == 0) {
Set<Project> projects;
@@ -572,7 +574,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
try {
reloadOk[0] = ((ApplicationImpl)app).getStateStore().reload(causes, components);
}
catch (StateStorage.StateStorageException e) {
@@ -639,6 +640,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
try {
LOG.info("[RELOAD] Reloading project/components...");
reloadOk[0] = ((ProjectEx)project).getStateStore().reload(causes);
}
catch (StateStorage.StateStorageException e) {
@@ -725,6 +727,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
}
private void registerProjectToReload(final Project project, final VirtualFile cause, final StateStorage storage) {
LOG.info("[RELOAD] Registering project to reload.");
if (project != null) {
synchronized (myChangedProjectFiles) {
List<Pair<VirtualFile, StateStorage>> changedProjectFiles = myChangedProjectFiles.get(project);
@@ -743,6 +747,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements NamedJDOMExt
myChangedFilesAlarm.cancelAllRequests();
myChangedFilesAlarm.addRequest(new Runnable() {
public void run() {
LOG.info("[RELOAD] Scheduling reload application & project, myReloadBlockCount = " + myReloadBlockCount);
if (myReloadBlockCount.get() == 0) {
scheduleReloadApplicationAndProject();
}
@@ -562,6 +562,7 @@ automatic.renamer.rename.to.column=Rename To
rename.0.and.its.usages.to=Rename {0} and its usages to:
rename.variables=Rename &variables
rename.inheritors=Rename &inheritors
rename.tests=Rename &tests
rename.parameters.hierarchy=Rename parameters in hier&archy
rename.bound.forms=Rename bound &forms
inner.class.0.is.already.defined.in.class.1=Inner class {0} is already defined in class {1}.\nContinue anyway?
@@ -577,8 +578,11 @@ rename.bound.forms.title=Rename bound forms
rename.forms.with.the.following.names.to=Rename forms with the following names to:
entity.name.form=Form
rename.inheritors.title=Rename Inheritors
rename.tests.title=Rename Tests
rename.inheritors.with.the.following.names.to=Rename inheritors with the following names to:
rename.tests.with.the.following.names.to=Rename tests with the following names to:
entity.name.inheritor=Inheritor
entity.name.test=Test
unused.overriding.methods.title=Unused Overriding Methods
there.are.unused.methods.that.override.methods.you.delete=There are unused methods that override methods you delete.
choose.the.ones.you.want.to.be.deleted=Choose the ones you want to be deleted.
@@ -22,19 +22,13 @@
<keyboard-shortcut first-keystroke="shift alt C" />
</action>
<action id="CheckinProject" />
<action id="CloseActiveTab">
<keyboard-shortcut first-keystroke="control F4" />
<keyboard-shortcut first-keystroke="control W" />
</action>
<action id="CloseActiveTab" />
<action id="CloseAllEditors">
<keyboard-shortcut first-keystroke="shift control F4" />
<keyboard-shortcut first-keystroke="shift control W" />
</action>
<action id="CloseEditor" />
<action id="CloseWindow">
<keyboard-shortcut first-keystroke="control F4" />
<keyboard-shortcut first-keystroke="control W" />
</action>
<action id="CloseWindow" />
<action id="CodeInspection.OnEditor" />
<action id="CollapseAllRegions">
<keyboard-shortcut first-keystroke="shift control DIVIDE" />
@@ -224,7 +224,7 @@
<keyboard-shortcut first-keystroke="UP"/>
<keyboard-shortcut first-keystroke="control P"/>
</action>
<action id="CloseEditor">
<action id="CloseContent">
<keyboard-shortcut first-keystroke="control F4"/>
<keyboard-shortcut first-keystroke="control X" second-keystroke="K"/>
</action>
@@ -6,7 +6,7 @@
<action id="CloseActiveTab">
<keyboard-shortcut first-keystroke="shift control 4" />
</action>
<action id="CloseEditor">
<action id="CloseContent">
<keyboard-shortcut first-keystroke="control 4" />
</action>
<action id="CompileDirty">
@@ -42,20 +42,16 @@
<keyboard-shortcut first-keystroke="control alt BACK_SLASH" />
</action>
<action id="CloneElement" />
<action id="CloseActiveTab">
<keyboard-shortcut first-keystroke="control W" />
</action>
<action id="CloseActiveTab" />
<action id="CloseAllEditors">
<keyboard-shortcut first-keystroke="shift control W" />
<keyboard-shortcut first-keystroke="shift control F4" />
</action>
<action id="CloseEditor">
<action id="CloseContent">
<keyboard-shortcut first-keystroke="control F4" />
<keyboard-shortcut first-keystroke="control W" />
</action>
<action id="CloseWindow">
<keyboard-shortcut first-keystroke="control W" />
</action>
<action id="CloseWindow" />
<action id="CodeCompletion">
<keyboard-shortcut first-keystroke="control SPACE" />
<keyboard-shortcut first-keystroke="control BACK_SLASH" />
@@ -173,9 +173,12 @@ public abstract class AbstractRecordsTable implements Disposable, Forceable {
public void deleteRecord(final int record) {
ensureFreeRecordsScanned();
setSize(record, -1);
clearDeletedRecord(record);
myFreeRecordsList.add(record);
}
protected abstract void clearDeletedRecord(int record);
public int getVersion() {
return myStorage.getInt(HEADER_VERSION_OFFSET);
}
@@ -47,4 +47,8 @@ class RecordsTable extends AbstractRecordsTable {
protected byte[] getZeros() {
return ZEROES;
}
@Override
protected void clearDeletedRecord(int record) {
}
}
@@ -47,6 +47,11 @@ class RefCountingRecordsTable extends AbstractRecordsTable {
return ZEROES;
}
@Override
protected void clearDeletedRecord(int record) {
myStorage.putInt(getOffset(record, REF_COUNT_OFFSET), 0);
}
public void incRefCount(int record) {
markDirty();
@@ -0,0 +1,35 @@
/*
* 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.xdebugger.frame;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public class ImmediateFullValueEvaluator extends XFullValueEvaluator {
private String myFullValue;
public ImmediateFullValueEvaluator(@NotNull String linkText, @NotNull String fullValue) {
super(linkText);
myFullValue = fullValue;
}
@Override
public void startEvaluation(@NotNull XFullValueEvaluationCallback callback) {
callback.evaluated(myFullValue);
}
}
@@ -0,0 +1,52 @@
/*
* 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.xdebugger.frame;
import org.jetbrains.annotations.NotNull;
/**
* Supports asynchronous fetching full text of a value. If full text is already computed use {@link ImmediateFullValueEvaluator}
* @see XValueNode#setFullValueEvaluator
* @see ImmediateFullValueEvaluator
*
* @author nik
*/
public abstract class XFullValueEvaluator {
private String myLinkText;
/**
* @param linkText text of the link what will be appended to a variables tree node text
*/
protected XFullValueEvaluator(@NotNull String linkText) {
myLinkText = linkText;
}
/**
* Start fetching full text of the value. Note that this method is called from the Event Dispatch Thread so it should return quickly
* @param callback used to notify that the full text has been successfully evaluated or an error occurs
*/
public abstract void startEvaluation(@NotNull XFullValueEvaluationCallback callback);
public String getLinkText() {
return myLinkText;
}
public interface XFullValueEvaluationCallback {
void evaluated(@NotNull String fullValue);
void errorOccurred(@NotNull String errorMessage);
}
}
@@ -24,7 +24,7 @@ import org.jetbrains.annotations.Nullable;
public abstract class XValueModifier {
/**
* Start modification of the value. Note that this methods is called from the Event Dispatch Thread so it should return quickly
* Start modification of the value. Note that this method is called from the Event Dispatch Thread so it should return quickly
* @param expression new value
* @param callback used to notify that value has been successfully modified or an error occurs
*/
@@ -38,9 +38,8 @@ public interface XValueNode extends Obsolescent {
/**
* If string representation of the value is too long to show in the tree pass truncated value to {@link #setPresentation(String, javax.swing.Icon, String, String, boolean)}
* method and call this method to provide full value.
* This will add a link to the node and show <code>fullValue</code> text if a user click on that link.
* @param fullValue full text of the value. Will be shown in popup window
* @param linkText text of the link. Will be appended to the node text
* This will add a link to the node and show popup with full value if an user clicks on that link.
* @param fullValueEvaluator will be used to obtain full text of the value
*/
void setFullValue(@NotNull String fullValue, @NotNull String linkText);
void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator);
}
@@ -30,6 +30,7 @@ import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.frame.XValueNode;
import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
@@ -90,7 +91,7 @@ public class XValueHint extends AbstractValueHint {
});
}
public void setFullValue(@NotNull String fullValue, @NotNull String linkText) {
public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
//todo[nik] implement?
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -90,26 +91,51 @@ public class DebuggerUIUtil {
return new RelativePoint(editor.getContentComponent(), p);
}
public static void showValuePopup(@NotNull String text, @NotNull MouseEvent event, @NotNull Project project) {
JTextArea textArea = new JTextArea(text);
public static void showValuePopup(@NotNull XFullValueEvaluator text, @NotNull MouseEvent event, @NotNull Project project) {
final JTextArea textArea = new JTextArea("Evaluating...");
text.startEvaluation(new FullValueEvaluationCallbackImpl(textArea));
textArea.setEditable(false);
textArea.setBackground(HintUtil.INFORMATION_COLOR);
textArea.setLineWrap(false);
final JScrollPane component = ScrollPaneFactory.createScrollPane(textArea);
final Dimension frameSize = WindowManager.getInstance().getFrame(project).getSize();
final Dimension size = new Dimension(frameSize.width / 2, frameSize.height / 2);
component.setPreferredSize(size);
component.setBorder(null);
final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(component, null)
.setResizable(true)
.setMovable(true)
.setDimensionServiceKey(project, "XDebugger.FullValuePopup", false)
.setRequestFocus(false)
.createPopup();
final Dimension size = textArea.getPreferredSize();
final Component parentComponent = event.getComponent();
final Dimension frameSize = WindowManager.getInstance().getFrame(project).getSize();
size.width = Math.min(size.width, frameSize.width / 2);
size.height = Math.min(size.height, frameSize.height / 2);
component.setPreferredSize(size);
RelativePoint point = new RelativePoint(parentComponent, new Point(event.getX()-size.width, event.getY()-size.height));
popup.show(point);
}
private static class FullValueEvaluationCallbackImpl implements XFullValueEvaluator.XFullValueEvaluationCallback {
private final JTextArea myTextArea;
public FullValueEvaluationCallbackImpl(JTextArea textArea) {
myTextArea = textArea;
}
public void evaluated(@NotNull final String fullValue) {
invokeOnEventDispatch(new Runnable() {
public void run() {
myTextArea.setText(fullValue);
}
});
}
public void errorOccurred(@NotNull final String errorMessage) {
invokeOnEventDispatch(new Runnable() {
public void run() {
myTextArea.setForeground(XDebuggerUIConstants.ERROR_MESSAGE_ATTRIBUTES.getFgColor());
myTextArea.setText(errorMessage);
}
});
}
}
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.StringBuilderSpinAllocator;
import com.intellij.xdebugger.frame.XCompositeNode;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.frame.XValueNode;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
@@ -39,10 +40,9 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
private String myName;
private String myType;
private String myValue;
private String myFullValue;
private XFullValueEvaluator myFullValueEvaluator;
private String mySeparator;
private boolean myChanged;
private String myLinkText;
public XValueNodeImpl(XDebuggerTree tree, final XDebuggerTreeNode parent, final XValue value) {
super(tree, parent, value);
@@ -74,11 +74,10 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
});
}
public void setFullValue(@NotNull final String fullValue, @NotNull final String linkText) {
public void setFullValueEvaluator(@NotNull final XFullValueEvaluator fullValueEvaluator) {
DebuggerUIUtil.invokeOnEventDispatch(new Runnable() {
public void run() {
myLinkText = linkText;
myFullValue = fullValue;
myFullValueEvaluator = fullValueEvaluator;
fireNodeChanged();
}
});
@@ -122,11 +121,11 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
@Override
public XDebuggerNodeLink getLink() {
if (myFullValue != null) {
return new XDebuggerNodeLink(myLinkText) {
if (myFullValueEvaluator != null) {
return new XDebuggerNodeLink(myFullValueEvaluator.getLinkText()) {
@Override
public void onClick(MouseEvent event) {
DebuggerUIUtil.showValuePopup(myFullValue, event, myTree.getProject());
DebuggerUIUtil.showValuePopup(myFullValueEvaluator, event, myTree.getProject());
}
};
}
@@ -135,9 +134,6 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
@Nullable
public String getValue() {
if (myFullValue != null) {
return myFullValue;
}
return myValue;
}
@@ -553,7 +553,7 @@ public class TestNGUtil implements TestFramework
}
public static boolean isTestngXML(final VirtualFile virtualFile) {
if (virtualFile.getName().endsWith("xml")) {
if ("xml".equalsIgnoreCase(virtualFile.getExtension())) {
final String result = NanoXmlUtil.parseHeader(virtualFile).getRootTagLocalName();
if (result != null && result.equals(SUITE_TAG_NAME)) {
return true;
+1
View File
@@ -1016,6 +1016,7 @@
<automaticRenamerFactory implementation="com.intellij.refactoring.rename.naming.AutomaticVariableRenamerFactory"/>
<automaticRenamerFactory implementation="com.intellij.refactoring.rename.naming.AutomaticParametersRenamerFactory"/>
<automaticRenamerFactory implementation="com.intellij.refactoring.rename.naming.AutomaticInheritorRenamerFactory"/>
<automaticRenamerFactory implementation="com.intellij.refactoring.rename.naming.AutomaticTestRenamerFactory"/>
<automaticRenamerFactory implementation="com.intellij.refactoring.rename.naming.ConstructorParameterOnFieldRenameRenamerFactory"/>
<nameSuggestionProvider implementation="com.intellij.refactoring.rename.JavaNameSuggestionProvider" id="java"/>