Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alexander Lobas
2012-05-16 16:59:20 +04:00
65 changed files with 813 additions and 407 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,9 +15,10 @@
*/
package com.intellij.psi;
import com.intellij.util.ArrayFactory;
/**
* Represents a PSI element which can be used as the value of an annotation
* element.
* Represents a PSI element which can be used as the value of an annotation element.
*
* @author ven
*/
@@ -26,4 +27,11 @@ public interface PsiAnnotationMemberValue extends PsiElement {
* The empty array of PSI annotation member values which can be reused to avoid unnecessary allocations.
*/
PsiAnnotationMemberValue[] EMPTY_ARRAY = new PsiAnnotationMemberValue[0];
ArrayFactory<PsiAnnotationMemberValue> ARRAY_FACTORY = new ArrayFactory<PsiAnnotationMemberValue>() {
@Override
public PsiAnnotationMemberValue[] create(final int count) {
return count == 0 ? PsiAnnotationMemberValue.EMPTY_ARRAY : new PsiAnnotationMemberValue[count];
}
};
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.psi;
import com.intellij.util.ArrayFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,6 +32,13 @@ public interface PsiCatchSection extends PsiElement {
*/
PsiCatchSection[] EMPTY_ARRAY = new PsiCatchSection[0];
ArrayFactory<PsiCatchSection> ARRAY_FACTORY = new ArrayFactory<PsiCatchSection>() {
@Override
public PsiCatchSection[] create(final int count) {
return count == 0 ? PsiCatchSection.EMPTY_ARRAY : new PsiCatchSection[count];
}
};
/**
* Returns the variable in which the caught exception is captured.
*
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.psi;
import com.intellij.util.ArrayFactory;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import org.jetbrains.annotations.Nullable;
@@ -28,6 +29,13 @@ public interface PsiExpression extends PsiAnnotationMemberValue {
*/
PsiExpression[] EMPTY_ARRAY = new PsiExpression[0];
ArrayFactory<PsiExpression> ARRAY_FACTORY = new ArrayFactory<PsiExpression>() {
@Override
public PsiExpression[] create(final int count) {
return count == 0 ? PsiExpression.EMPTY_ARRAY : new PsiExpression[count];
}
};
Function<PsiExpression, PsiType> EXPRESSION_TO_TYPE = new NullableFunction<PsiExpression, PsiType>() {
@Override
public PsiType fun(final PsiExpression expression) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.psi;
import com.intellij.util.ArrayFactory;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -32,6 +33,13 @@ public interface PsiNameValuePair extends PsiElement {
*/
PsiNameValuePair[] EMPTY_ARRAY = new PsiNameValuePair[0];
ArrayFactory<PsiNameValuePair> ARRAY_FACTORY = new ArrayFactory<PsiNameValuePair>() {
@Override
public PsiNameValuePair[] create(final int count) {
return count == 0 ? PsiNameValuePair.EMPTY_ARRAY : new PsiNameValuePair[count];
}
};
/**
* Returns the identifier specifying the name of the element.
*
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,6 +15,8 @@
*/
package com.intellij.psi;
import com.intellij.util.ArrayFactory;
/**
* Represents a Java statement.
*/
@@ -23,4 +25,11 @@ public interface PsiStatement extends PsiElement {
* The empty array of PSI statements which can be reused to avoid unnecessary allocations.
*/
PsiStatement[] EMPTY_ARRAY = new PsiStatement[0];
ArrayFactory<PsiStatement> ARRAY_FACTORY = new ArrayFactory<PsiStatement>() {
@Override
public PsiStatement[] create(final int count) {
return count == 0 ? PsiStatement.EMPTY_ARRAY : new PsiStatement[count];
}
};
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.psi;
import com.intellij.util.ArrayFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,6 +29,13 @@ public interface PsiTypeElement extends PsiElement,PsiAnnotationOwner {
*/
PsiTypeElement[] EMPTY_ARRAY = new PsiTypeElement[0];
ArrayFactory<PsiTypeElement> ARRAY_FACTORY = new ArrayFactory<PsiTypeElement>() {
@Override
public PsiTypeElement[] create(final int count) {
return count == 0 ? EMPTY_ARRAY : new PsiTypeElement[count];
}
};
/**
* Returns the type referenced by the type element.
*
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -24,7 +24,6 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.impl.light.LightClassReference;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.impl.source.PsiImmediateClassType;
import com.intellij.psi.impl.source.tree.CompositeElement;
@@ -493,10 +492,10 @@ public class PsiImplUtil {
@Nullable
public static ASTNode findStatementChild(CompositePsiElement statement) {
if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED){
if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED) {
ApplicationManager.getApplication().assertReadAccessAllowed();
}
for(ASTNode element = statement.getFirstChildNode(); element != null; element = element.getTreeNext()){
for (ASTNode element = statement.getFirstChildNode(); element != null; element = element.getTreeNext()) {
if (element.getPsi() instanceof PsiStatement) return element;
}
return null;
@@ -512,10 +511,8 @@ public class PsiImplUtil {
}
}
PsiStatement[] result = Constants.PSI_STATEMENT_ARRAY_CONSTRUCTOR.newPsiElementArray(count);
if (count == 0) {
return result;
}
PsiStatement[] result = PsiStatement.ARRAY_FACTORY.create(count);
if (count == 0) return result;
int idx = 0;
for (ASTNode child = psiCodeBlock.getFirstChildNode(); child != null && idx < count; child = child.getTreeNext()) {
if (child.getPsi() instanceof PsiStatement) {
@@ -257,7 +257,7 @@ public class ClsClassImpl extends ClsRepositoryPsiElement<PsiClassStub<?>> imple
@NotNull
@Override
public List<PsiClass> getOwnInnerClasses() {
return Arrays.asList(getStub().getChildrenByType(JavaStubElementTypes.CLASS, ARRAY_FACTORY));
return Arrays.asList(getStub().getChildrenByType(JavaStubElementTypes.CLASS, PsiClass.ARRAY_FACTORY));
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -15,119 +15,11 @@
*/
package com.intellij.psi.impl.source;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.tree.TokenSet;
public interface Constants extends ElementType {
PsiElementArrayConstructor<PsiClass> PSI_CLASS_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiClass>() {
@Override
public PsiClass[] newPsiElementArray(int length) {
return length == 0 ? PsiClass.EMPTY_ARRAY : new PsiClass[length];
}
};
PsiElementArrayConstructor<PsiField> PSI_FIELD_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiField>() {
@Override
public PsiField[] newPsiElementArray(int length) {
return length == 0 ? PsiField.EMPTY_ARRAY : new PsiField[length];
}
};
PsiElementArrayConstructor<PsiMethod> PSI_METHOD_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiMethod>() {
@Override
public PsiMethod[] newPsiElementArray(int length) {
return length == 0 ? PsiMethod.EMPTY_ARRAY : new PsiMethod[length];
}
};
PsiElementArrayConstructor<PsiClassInitializer> PSI_CLASS_INITIALIZER_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiClassInitializer>() {
@Override
public PsiClassInitializer[] newPsiElementArray(int length) {
return length == 0 ? PsiClassInitializer.EMPTY_ARRAY : new PsiClassInitializer[length];
}
};
PsiElementArrayConstructor<PsiParameter> PSI_PARAMETER_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiParameter>() {
@Override
public PsiParameter[] newPsiElementArray(int length) {
return length == 0 ? PsiParameter.EMPTY_ARRAY : new PsiParameter[length];
}
};
PsiElementArrayConstructor<PsiCatchSection> PSI_CATCH_SECTION_ARRAYS_CONSTRUCTOR = new PsiElementArrayConstructor<PsiCatchSection>() {
@Override
public PsiCatchSection[] newPsiElementArray(int length) {
return length == 0 ? PsiCatchSection.EMPTY_ARRAY : new PsiCatchSection[length];
}
};
PsiElementArrayConstructor<PsiJavaCodeReferenceElement> PSI_REFERENCE_ELEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiJavaCodeReferenceElement>() {
@Override
public PsiJavaCodeReferenceElement[] newPsiElementArray(int length) {
return length == 0 ? PsiJavaCodeReferenceElement.EMPTY_ARRAY : new PsiJavaCodeReferenceElement[length];
}
};
PsiElementArrayConstructor<PsiStatement> PSI_STATEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiStatement>() {
@Override
public PsiStatement[] newPsiElementArray(int length) {
return length == 0 ? PsiStatement.EMPTY_ARRAY : new PsiStatement[length];
}
};
PsiElementArrayConstructor<PsiExpression> PSI_EXPRESSION_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiExpression>() {
@Override
public PsiExpression[] newPsiElementArray(int length) {
return length == 0 ? PsiExpression.EMPTY_ARRAY : new PsiExpression[length];
}
};
PsiElementArrayConstructor<PsiImportStatement> PSI_IMPORT_STATEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiImportStatement>() {
@Override
public PsiImportStatement[] newPsiElementArray(int length) {
return length == 0 ? PsiImportStatement.EMPTY_ARRAY : new PsiImportStatement[length];
}
};
PsiElementArrayConstructor<PsiImportStaticStatement> PSI_IMPORT_STATIC_STATEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiImportStaticStatement>() {
@Override
public PsiImportStaticStatement[] newPsiElementArray(int length) {
return length == 0 ? PsiImportStaticStatement.EMPTY_ARRAY : new PsiImportStaticStatement[length];
}
};
PsiElementArrayConstructor<PsiImportStatementBase> PSI_IMPORT_STATEMENT_BASE_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiImportStatementBase>() {
@Override
public PsiImportStatementBase[] newPsiElementArray(int length) {
return length == 0 ? PsiImportStatementBase.EMPTY_ARRAY : new PsiImportStatementBase[length];
}
};
PsiElementArrayConstructor<PsiAnnotationMemberValue> PSI_ANNOTATION_MEMBER_VALUE_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiAnnotationMemberValue>() {
@Override
public PsiAnnotationMemberValue[] newPsiElementArray(int length) {
return length == 0 ? PsiAnnotationMemberValue.EMPTY_ARRAY : new PsiAnnotationMemberValue[length];
}
};
PsiElementArrayConstructor<PsiNameValuePair> PSI_NAME_VALUE_PAIR_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiNameValuePair>() {
@Override
public PsiNameValuePair[] newPsiElementArray(int length) {
return length == 0 ? PsiNameValuePair.EMPTY_ARRAY : new PsiNameValuePair[length];
}
};
PsiElementArrayConstructor<PsiAnnotation> PSI_ANNOTATION_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiAnnotation>() {
@Override
public PsiAnnotation[] newPsiElementArray(int length) {
return length == 0 ? PsiAnnotation.EMPTY_ARRAY : new PsiAnnotation[length];
}
};
TokenSet CLASS_BIT_SET = TokenSet.create(JavaElementType.CLASS, JavaElementType.ANONYMOUS_CLASS, JavaElementType.ENUM_CONSTANT_INITIALIZER);
TokenSet FIELD_BIT_SET = TokenSet.create(JavaElementType.FIELD, JavaElementType.ENUM_CONSTANT);
TokenSet METHOD_BIT_SET = TokenSet.create(JavaElementType.METHOD, JavaElementType.ANNOTATION_METHOD);
@@ -311,7 +311,7 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
@NotNull
@Override
public List<PsiClass> getOwnInnerClasses() {
return Arrays.asList(getStubOrPsiChildren(JavaStubElementTypes.CLASS, ARRAY_FACTORY));
return Arrays.asList(getStubOrPsiChildren(JavaStubElementTypes.CLASS, PsiClass.ARRAY_FACTORY));
}
@Override
@@ -589,7 +589,7 @@ public class PsiClassImpl extends JavaStubPsiElement<PsiClassStub<?>> implements
final StubBasedPsiElementBase<?> context = (StubBasedPsiElementBase)parentStub.getPsi();
@SuppressWarnings("unchecked")
PsiClass[] classesInScope = (PsiClass[])parentStub.getChildrenByType(Constants.CLASS_BIT_SET, ARRAY_FACTORY);
PsiClass[] classesInScope = (PsiClass[])parentStub.getChildrenByType(Constants.CLASS_BIT_SET, PsiClass.ARRAY_FACTORY);
boolean needPreciseContext = false;
if (classesInScope.length > 1) {
@@ -89,7 +89,7 @@ public abstract class PsiJavaFileBaseImpl extends PsiFileImpl implements PsiJava
return stub.getChildrenByType(JavaStubElementTypes.CLASS, PsiClass.ARRAY_FACTORY);
}
return calcTreeElement().getChildrenAsPsiElements(Constants.CLASS_BIT_SET, Constants.PSI_CLASS_ARRAY_CONSTRUCTOR);
return calcTreeElement().getChildrenAsPsiElements(Constants.CLASS_BIT_SET, PsiClass.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -46,7 +46,7 @@ public class PsiMethodReceiverImpl extends CompositePsiElement implements PsiMet
@Override
@NotNull
public PsiAnnotation[] getAnnotations() {
return getChildrenAsPsiElements(ElementType.ANNOTATIONS, Constants.PSI_ANNOTATION_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(ElementType.ANNOTATIONS, PsiAnnotation.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -40,7 +40,7 @@ public final class PsiReferenceListImpl extends JavaStubPsiElement<PsiClassRefer
@Override
@NotNull
public PsiJavaCodeReferenceElement[] getReferenceElements() {
return calcTreeElement().getChildrenAsPsiElements(REFERENCE_BIT_SET, Constants.PSI_REFERENCE_ELEMENT_ARRAY_CONSTRUCTOR);
return calcTreeElement().getChildrenAsPsiElements(REFERENCE_BIT_SET, PsiJavaCodeReferenceElement.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -21,7 +21,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleSettingsFacade;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.javadoc.PsiDocComment;
@@ -30,6 +29,7 @@ import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.ArrayFactory;
import com.intellij.util.CharTable;
import com.intellij.util.text.CharArrayUtil;
import org.jetbrains.annotations.NotNull;
@@ -41,10 +41,10 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.javadoc.PsiDocCommentImpl");
private static final TokenSet TAG_BIT_SET = TokenSet.create(DOC_TAG);
private static final PsiElementArrayConstructor<PsiDocTag> PSI_TAG_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiDocTag>() {
private static final ArrayFactory<PsiDocTag> ARRAY_FACTORY = new ArrayFactory<PsiDocTag>() {
@Override
public PsiDocTag[] newPsiElementArray(int length) {
return length == 0 ? PsiDocTag.EMPTY_ARRAY : new PsiDocTag[length];
public PsiDocTag[] create(final int count) {
return count == 0 ? PsiDocTag.EMPTY_ARRAY : new PsiDocTag[count];
}
};
@@ -86,7 +86,7 @@ public class PsiDocCommentImpl extends LazyParseablePsiElement implements PsiDoc
@Override
@NotNull
public PsiDocTag[] getTags() {
return getChildrenAsPsiElements(TAG_BIT_SET, PSI_TAG_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(TAG_BIT_SET, ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -21,9 +21,8 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
@@ -31,23 +30,16 @@ 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;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Constants {
private static final TokenSet VALUE_BIT_SET = TokenSet.create(new IElementType[]{
JAVA_CODE_REFERENCE,
DOC_TAG_VALUE_TOKEN,
DOC_METHOD_OR_FIELD_REF,
DOC_PARAMETER_REF,
DOC_COMMENT_DATA,
DOC_INLINE_TAG,
DOC_REFERENCE_HOLDER
});
private static final TokenSet VALUE_BIT_SET = TokenSet.create(
JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF,
DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER);
public PsiDocTagImpl() {
super(DOC_TAG);
@@ -70,7 +62,7 @@ public class PsiDocTagImpl extends CompositePsiElement implements PsiDocTag, Con
@Override
public PsiElement[] getDataElements() {
return getChildrenAsPsiElements(VALUE_BIT_SET, PsiElementArrayConstructor.PSI_ELEMENT_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(VALUE_BIT_SET, PsiElement.ARRAY_FACTORY);
}
@Override
@@ -17,8 +17,6 @@ package com.intellij.psi.impl.source.tree;
import com.intellij.psi.JavaDocTokenType;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiTypeElement;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
import com.intellij.psi.tree.TokenSet;
public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElementType, JavaDocElementType {
@@ -76,12 +74,6 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
);
TokenSet TYPES_BIT_SET = TokenSet.create(TYPE);
PsiElementArrayConstructor<PsiTypeElement> PSI_TYPE_ELEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiTypeElement>() {
@Override
public PsiTypeElement[] newPsiElementArray(int length) {
return length > 0 ? new PsiTypeElement[length] : PsiTypeElement.EMPTY_ARRAY;
}
};
TokenSet IMPORT_STATEMENT_BIT_SET = TokenSet.create(IMPORT_STATEMENT);
TokenSet IMPORT_STATIC_STATEMENT_BIT_SET = TokenSet.create(IMPORT_STATIC_STATEMENT);
TokenSet IMPORT_STATEMENT_BASE_BIT_SET = TokenSet.create(IMPORT_STATEMENT, IMPORT_STATIC_STATEMENT);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -47,7 +47,7 @@ public class PsiAnnotationParameterListImpl extends PsiCommaSeparatedListImpl im
public PsiNameValuePair[] getAttributes() {
PsiNameValuePair[] cachedMembers = myCachedMembers;
if (cachedMembers == null) {
myCachedMembers = cachedMembers = getChildrenAsPsiElements(NAME_VALUE_PAIR_BIT_SET, PSI_NAME_VALUE_PAIR_ARRAY_CONSTRUCTOR);
myCachedMembers = cachedMembers = getChildrenAsPsiElements(NAME_VALUE_PAIR_BIT_SET, PsiNameValuePair.ARRAY_FACTORY);
}
return cachedMembers;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -35,7 +35,7 @@ public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement impl
@Override
@NotNull
public PsiExpression[] getInitializers(){
return getChildrenAsPsiElements(EXPRESSION_BIT_SET, PSI_EXPRESSION_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
}
@Override
@@ -128,16 +128,15 @@ public class PsiArrayInitializerExpressionImpl extends ExpressionPsiElement impl
if (ElementType.EXPRESSION_BIT_SET.contains(first.getElementType())) {
final CharTable charTab = SharedImplUtil.findCharTableByTree(this);
ASTNode element = first;
for (ASTNode child = element.getTreeNext(); child != null; child = child.getTreeNext()) {
for (ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()) {
if (child.getElementType() == COMMA) break;
if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, charTab, getManager());
super.addInternal(comma, comma, element, Boolean.FALSE);
super.addInternal(comma, comma, first, Boolean.FALSE);
break;
}
}
for (ASTNode child = element.getTreePrev(); child != null; child = child.getTreePrev()) {
for (ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()) {
if (child.getElementType() == COMMA) break;
if (ElementType.EXPRESSION_BIT_SET.contains(child.getElementType())) {
TreeElement comma = Factory.createSingleLeafElement(COMMA, ",", 0, 1, charTab, getManager());
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -38,7 +38,7 @@ public class PsiArrayInitializerMemberValueImpl extends PsiCommaSeparatedListImp
@Override
@NotNull
public PsiAnnotationMemberValue[] getInitializers() {
return getChildrenAsPsiElements(ANNOTATION_MEMBER_VALUE_BIT_SET, PSI_ANNOTATION_MEMBER_VALUE_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(ANNOTATION_MEMBER_VALUE_BIT_SET, PsiAnnotationMemberValue.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -17,7 +17,6 @@ package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.scope.ElementClassHint;
@@ -33,7 +32,7 @@ public class PsiDeclarationStatementImpl extends CompositePsiElement implements
@Override
@NotNull
public PsiElement[] getDeclaredElements() {
return getChildrenAsPsiElements(DECLARED_ELEMENT_BIT_SET, PsiElementArrayConstructor.PSI_ELEMENT_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(DECLARED_ELEMENT_BIT_SET, PsiElement.ARRAY_FACTORY);
}
private static final TokenSet DECLARED_ELEMENT_BIT_SET = TokenSet.create(JavaElementType.LOCAL_VARIABLE, JavaElementType.CLASS);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -19,7 +19,6 @@ import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
@@ -36,7 +35,7 @@ public class PsiExpressionListImpl extends CompositePsiElement implements PsiExp
@Override
@NotNull
public PsiExpression[] getExpressions() {
return getChildrenAsPsiElements(ElementType.EXPRESSION_BIT_SET, Constants.PSI_EXPRESSION_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(ElementType.EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -21,26 +21,26 @@ import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.JavaDocElementType;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.psi.javadoc.PsiInlineDocTag;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlineDocTag, Constants {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiInlineDocTagImpl");
private static final TokenSet VALUE_BIT_SET = TokenSet.create(JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_METHOD_OR_FIELD_REF,
DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, WHITE_SPACE, DOC_COMMENT_BAD_CHARACTER);
private static final TokenSet VALUE_BIT_SET = TokenSet.create(
JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_METHOD_OR_FIELD_REF, DOC_COMMENT_DATA, DOC_INLINE_TAG,
DOC_REFERENCE_HOLDER, WHITE_SPACE, DOC_COMMENT_BAD_CHARACTER);
public PsiInlineDocTagImpl() {
super(DOC_INLINE_TAG);
@@ -62,7 +62,7 @@ public class PsiInlineDocTagImpl extends CompositePsiElement implements PsiInlin
@Override
public PsiElement[] getDataElements() {
return getChildrenAsPsiElements(VALUE_BIT_SET, PsiElementArrayConstructor.PSI_ELEMENT_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(VALUE_BIT_SET, PsiElement.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -20,7 +20,6 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.resolve.reference.impl.PsiPolyVariantCachingReference;
@@ -93,12 +92,12 @@ public class PsiNewExpressionImpl extends ExpressionPsiElement implements PsiNew
@Override
@NotNull
public PsiExpression[] getArrayDimensions() {
PsiExpression[] expressions = getChildrenAsPsiElements(ElementType.ARRAY_DIMENSION_BIT_SET, Constants.PSI_EXPRESSION_ARRAY_CONSTRUCTOR);
PsiExpression[] expressions = getChildrenAsPsiElements(ElementType.ARRAY_DIMENSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
PsiExpression qualifier = getQualifier();
if (qualifier == null){
if (qualifier == null) {
return expressions;
}
else{
else {
LOG.assertTrue(expressions[0] == qualifier);
PsiExpression[] expressions1 = new PsiExpression[expressions.length - 1];
System.arraycopy(expressions, 1, expressions1, 0, expressions1.length);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.resolve.JavaResolveCache;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.ElementType;
@@ -28,7 +27,9 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PsiPolyadicExpressionImpl extends ExpressionPsiElement implements PsiPolyadicExpression {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiPolyadicExpressionImpl");
@@ -57,13 +58,15 @@ public class PsiPolyadicExpressionImpl extends ExpressionPsiElement implements P
public PsiType getType() {
return JavaResolveCache.getInstance(getProject()).getType(this, MY_TYPE_EVALUATOR);
}
private static final Function<PsiPolyadicExpressionImpl,PsiType> MY_TYPE_EVALUATOR = new Function<PsiPolyadicExpressionImpl, PsiType>() {
private static final Function<PsiPolyadicExpressionImpl,PsiType> MY_TYPE_EVALUATOR = new NullableFunction<PsiPolyadicExpressionImpl, PsiType>() {
@Override
public PsiType fun(PsiPolyadicExpressionImpl expression) {
return doGetType(expression);
}
};
@Nullable
private static PsiType doGetType(PsiPolyadicExpressionImpl param) {
PsiExpression[] operands = param.getOperands();
PsiType lType = null;
@@ -80,7 +83,6 @@ public class PsiPolyadicExpressionImpl extends ExpressionPsiElement implements P
return lType;
}
@Override
public ASTNode findChildByRole(int role) {
LOG.assertTrue(ChildRole.isUnique(role));
@@ -124,7 +126,7 @@ public class PsiPolyadicExpressionImpl extends ExpressionPsiElement implements P
public PsiExpression[] getOperands() {
PsiExpression[] operands = cachedOperands;
if (operands == null) {
cachedOperands = operands = getChildrenAsPsiElements(ElementType.EXPRESSION_BIT_SET, Constants.PSI_EXPRESSION_ARRAY_CONSTRUCTOR);
cachedOperands = operands = getChildrenAsPsiElements(ElementType.EXPRESSION_BIT_SET, PsiExpression.ARRAY_FACTORY);
}
return operands;
}
@@ -140,4 +142,3 @@ public class PsiPolyadicExpressionImpl extends ExpressionPsiElement implements P
return "PsiPolyadicExpression: " + getText();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -38,7 +38,7 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement
@Override
@NotNull
public PsiTypeElement[] getTypeParameterElements() {
return getChildrenAsPsiElements(ElementType.TYPES_BIT_SET, ElementType.PSI_TYPE_ELEMENT_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements(ElementType.TYPES_BIT_SET, PsiTypeElement.ARRAY_FACTORY);
}
@Override
@@ -125,16 +125,15 @@ public class PsiReferenceParameterListImpl extends CompositePsiElement implement
final TreeElement firstAdded = super.addInternal(first, last, anchor, before);
if (first == last && first.getElementType() == JavaElementType.TYPE){
ASTNode element = first;
for(ASTNode child = element.getTreeNext(); child != null; child = child.getTreeNext()){
for(ASTNode child = first.getTreeNext(); child != null; child = child.getTreeNext()){
if (child.getElementType() == JavaTokenType.COMMA) break;
if (child.getElementType() == JavaElementType.TYPE){
TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager());
super.addInternal(comma, comma, element, Boolean.FALSE);
super.addInternal(comma, comma, first, Boolean.FALSE);
break;
}
}
for(ASTNode child = element.getTreePrev(); child != null; child = child.getTreePrev()){
for(ASTNode child = first.getTreePrev(); child != null; child = child.getTreePrev()){
if (child.getElementType() == JavaTokenType.COMMA) break;
if (child.getElementType() == JavaElementType.TYPE){
TreeElement comma = Factory.createSingleLeafElement(JavaTokenType.COMMA, ",", 0, 1, treeCharTab, getManager());
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -90,7 +90,7 @@ public class PsiTryStatementImpl extends CompositePsiElement implements PsiTrySt
@Override
@NotNull
public PsiCatchSection[] getCatchSections() {
return getChildrenAsPsiElements(CATCH_SECTION_BIT_SET, PSI_CATCH_SECTION_ARRAYS_CONSTRUCTOR);
return getChildrenAsPsiElements(CATCH_SECTION_BIT_SET, PsiCatchSection.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -38,8 +38,7 @@ public class PsiTypeParameterExtendsBoundsListImpl extends JavaStubPsiElement<Ps
@Override
@NotNull
public PsiJavaCodeReferenceElement[] getReferenceElements() {
return calcTreeElement().getChildrenAsPsiElements(Constants.JAVA_CODE_REFERENCE_BIT_SET,
Constants.PSI_REFERENCE_ELEMENT_ARRAY_CONSTRUCTOR);
return calcTreeElement().getChildrenAsPsiElements(Constants.JAVA_CODE_REFERENCE_BIT_SET, PsiJavaCodeReferenceElement.ARRAY_FACTORY);
}
@Override
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.UserDataHolder;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.util.ArrayFactory;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -42,6 +43,13 @@ public interface PsiElement extends UserDataHolder, Iconable {
*/
PsiElement[] EMPTY_ARRAY = new PsiElement[0];
ArrayFactory<PsiElement> ARRAY_FACTORY = new ArrayFactory<PsiElement>() {
@Override
public PsiElement[] create(final int count) {
return count == 0 ? EMPTY_ARRAY : new PsiElement[count];
}
};
/**
* Returns the project to which the PSI element belongs.
*
@@ -1,30 +0,0 @@
/*
* Copyright 2000-2009 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.impl.source;
import com.intellij.psi.PsiElement;
public interface PsiElementArrayConstructor<T extends PsiElement> {
PsiElementArrayConstructor<PsiElement> PSI_ELEMENT_ARRAY_CONSTRUCTOR = new PsiElementArrayConstructor<PsiElement>() {
@Override
public PsiElement[] newPsiElementArray(int length) {
return length == 0 ? PsiElement.EMPTY_ARRAY : new PsiElement[length];
}
};
T[] newPsiElementArray(int length);
}
@@ -52,6 +52,7 @@ import com.intellij.psi.stubs.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ILazyParseableElementType;
import com.intellij.psi.tree.IStubFileElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.reference.SoftReference;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.IncorrectOperationException;
@@ -755,7 +756,7 @@ public abstract class PsiFileImpl extends ElementBase implements PsiFileEx, PsiF
@Override
@NotNull
public PsiElement[] getChildren() {
return calcTreeElement().getChildrenAsPsiElements(null, PsiElementArrayConstructor.PSI_ELEMENT_ARRAY_CONSTRUCTOR);
return calcTreeElement().getChildrenAsPsiElements((TokenSet)null, PsiElement.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -420,7 +420,7 @@ public class CompositeElement extends TreeElement {
}
@Override
public ASTNode[] getChildren(TokenSet filter) {
public ASTNode[] getChildren(@Nullable TokenSet filter) {
int count = countChildren(filter);
if (count == 0) {
return EMPTY_ARRAY;
@@ -435,28 +435,8 @@ public class CompositeElement extends TreeElement {
return result;
}
@NotNull
public <T extends PsiElement> T[] getChildrenAsPsiElements(TokenSet filter, PsiElementArrayConstructor<T> constructor) {
ApplicationManager.getApplication().assertReadAccessAllowed();
int count = countChildren(filter);
T[] result = constructor.newPsiElementArray(count);
if (count == 0) {
return result;
}
int idx = 0;
for (ASTNode child = getFirstChildNode(); child != null && idx < count; child = child.getTreeNext()) {
if (filter == null || filter.contains(child.getElementType())) {
T element = (T)child.getPsi();
LOG.assertTrue(element != null, child);
result[idx++] = element;
}
}
return result;
}
@NotNull
public <T extends PsiElement> T[] getChildrenAsPsiElements(TokenSet filter, ArrayFactory<T> constructor) {
public <T extends PsiElement> T[] getChildrenAsPsiElements(@Nullable TokenSet filter, ArrayFactory<T> constructor) {
ApplicationManager.getApplication().assertReadAccessAllowed();
int count = countChildren(filter);
T[] result = constructor.create(count);
@@ -466,13 +446,14 @@ public class CompositeElement extends TreeElement {
int idx = 0;
for (ASTNode child = getFirstChildNode(); child != null && idx < count; child = child.getTreeNext()) {
if (filter == null || filter.contains(child.getElementType())) {
T element = (T)child.getPsi();
@SuppressWarnings("unchecked") T element = (T)child.getPsi();
LOG.assertTrue(element != null, child);
result[idx++] = element;
}
}
return result;
}
@NotNull
public <T extends PsiElement> T[] getChildrenAsPsiElements(@NotNull IElementType type, ArrayFactory<T> constructor) {
ApplicationManager.getApplication().assertReadAccessAllowed();
@@ -484,7 +465,7 @@ public class CompositeElement extends TreeElement {
int idx = 0;
for (ASTNode child = getFirstChildNode(); child != null && idx < count; child = child.getTreeNext()) {
if (type == child.getElementType()) {
T element = (T)child.getPsi();
@SuppressWarnings("unchecked") T element = (T)child.getPsi();
LOG.assertTrue(element != null, child);
result[idx++] = element;
}
@@ -492,7 +473,7 @@ public class CompositeElement extends TreeElement {
return result;
}
public int countChildren(TokenSet filter) {
public int countChildren(@Nullable TokenSet filter) {
// no lock is needed because all chameleons are expanded already
int count = 0;
for (ASTNode child = getFirstChildNode(); child != null; child = child.getTreeNext()) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -25,15 +25,15 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.SharedPsiElementImplUtil;
import com.intellij.psi.impl.ResolveScopeManager;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
import com.intellij.psi.impl.SharedPsiElementImplUtil;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -56,7 +56,7 @@ public abstract class CompositePsiElement extends CompositeElement implements Ps
@Override
@NotNull
public PsiElement[] getChildren() {
return getChildrenAsPsiElements(null, PsiElementArrayConstructor.PSI_ELEMENT_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements((TokenSet)null, PsiElement.ARRAY_FACTORY);
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -30,13 +30,13 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.ResolveScopeManager;
import com.intellij.psi.impl.SharedPsiElementImplUtil;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ReflectionCache;
import org.jetbrains.annotations.NotNull;
@@ -64,7 +64,7 @@ public class LazyParseablePsiElement extends LazyParseableElement implements Psi
@Override
@NotNull
public PsiElement[] getChildren() {
return getChildrenAsPsiElements(null, PsiElementArrayConstructor.PSI_ELEMENT_ARRAY_CONSTRUCTOR);
return getChildrenAsPsiElements((TokenSet)null, PsiElement.ARRAY_FACTORY);
}
@Nullable
@@ -39,6 +39,8 @@ import net.miginfocom.swing.MigLayout;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
@@ -56,6 +58,7 @@ class BeforeRunStepsPanel extends JPanel {
private final List<BeforeRunTask> originalTasks = new ArrayList<BeforeRunTask>();
private StepsBeforeRunListener myListener;
private final JPanel myPanel;
BeforeRunStepsPanel(StepsBeforeRunListener listener) {
myListener = listener;
@@ -64,7 +67,28 @@ class BeforeRunStepsPanel extends JPanel {
myList.getEmptyText().setText(ExecutionBundle.message("before.launch.panel.empty"));
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myList.setCellRenderer(new MyListCellRenderer());
ToolbarDecorator myDecorator = ToolbarDecorator.createDecorator(myList).setVisibleRowCount(4);
myModel.addListDataListener(new ListDataListener() {
@Override
public void intervalAdded(ListDataEvent e) {
adjustVisibleRowCount();
}
@Override
public void intervalRemoved(ListDataEvent e) {
adjustVisibleRowCount();
}
@Override
public void contentsChanged(ListDataEvent e) {
}
private void adjustVisibleRowCount() {
myList.setVisibleRowCount(Math.max(4, Math.min(8, myModel.getSize())));
}
});
ToolbarDecorator myDecorator = ToolbarDecorator.createDecorator(myList);
if (!SystemInfo.isMac) {
myDecorator.setAsTopToolbar();
}
@@ -72,7 +96,7 @@ class BeforeRunStepsPanel extends JPanel {
@Override
public void run(AnActionButton button) {
int index = myList.getSelectedIndex();
if (index ==-1)
if (index == -1)
return;
Pair<BeforeRunTask, BeforeRunTaskProvider<BeforeRunTask>> selection = getSelection();
if (selection == null)
@@ -97,12 +121,19 @@ class BeforeRunStepsPanel extends JPanel {
doAddAction(button);
}
});
myDecorator.setAddActionUpdater(new AnActionButtonUpdater() {
@Override
public boolean isEnabled(AnActionEvent e) {
return checkBeforeRunTasksAbility(true);
}
});
myShowSettingsBeforeRunCheckBox = new JCheckBox(ExecutionBundle.message("configuration.edit.before.run"));
setLayout(new MigLayout("fill, ins 0, gap 10"));
add(myShowSettingsBeforeRunCheckBox, "shrinky, wrap");
add(myDecorator.createPanel(), "grow, push");
setLayout(new MigLayout("fill, ins 0, gap 10, hidemode 3"));
add(myShowSettingsBeforeRunCheckBox, "shrinky, ay bottom, wrap");
myPanel = myDecorator.createPanel();
add(myPanel, "grow, push");
}
@Nullable
@@ -124,6 +155,8 @@ class BeforeRunStepsPanel extends JPanel {
myModel.replaceAll(originalTasks);
myShowSettingsBeforeRunCheckBox.setSelected(settings.isEditBeforeRun());
myShowSettingsBeforeRunCheckBox.setEnabled(!(myRunConfiguration instanceof UnknownRunConfiguration));
myPanel.setVisible(checkBeforeRunTasksAbility(false));
}
public List<BeforeRunTask> getTasks(boolean applyCurrentState) {
@@ -138,6 +171,26 @@ class BeforeRunStepsPanel extends JPanel {
return myShowSettingsBeforeRunCheckBox.isSelected();
}
private boolean checkBeforeRunTasksAbility(boolean checkOnlyAddAction) {
if (myRunConfiguration instanceof UnknownRunConfiguration) {
return false;
}
Set<Key> activeProviderKeys = getActiveProviderKeys();
final BeforeRunTaskProvider<BeforeRunTask>[] providers = Extensions.getExtensions(BeforeRunTaskProvider.EXTENSION_POINT_NAME,
myRunConfiguration.getProject());
for (final BeforeRunTaskProvider<BeforeRunTask> provider : providers) {
if (provider.createTask(myRunConfiguration) != null) {
if (!checkOnlyAddAction) {
return true;
}
else if (!provider.isSingleton() || !activeProviderKeys.contains(provider.getId())) {
return true;
}
}
}
return false;
}
void doAddAction(AnActionButton button) {
if (myRunConfiguration instanceof UnknownRunConfiguration) {
return;
@@ -146,16 +199,15 @@ class BeforeRunStepsPanel extends JPanel {
final JBPopupFactory popupFactory = JBPopupFactory.getInstance();
final BeforeRunTaskProvider<BeforeRunTask>[] providers = Extensions.getExtensions(BeforeRunTaskProvider.EXTENSION_POINT_NAME,
myRunConfiguration.getProject());
final List<Key> activeProviderKeys = getActiveProviderKeys();
Set<Key> activeProviderKeys = getActiveProviderKeys();
DefaultActionGroup actionGroup = new DefaultActionGroup(null, false);
for (final BeforeRunTaskProvider<BeforeRunTask> provider : providers) {
String providerName = provider.getName();
if (provider.createTask(myRunConfiguration) == null)
continue;
if (activeProviderKeys.contains(provider.getId()) && provider.isSingleton())
continue;
AnAction providerAction = new AnAction(providerName, null, provider.getIcon()) {
AnAction providerAction = new AnAction(provider.getName(), null, provider.getIcon()) {
@Override
public void actionPerformed(AnActionEvent e) {
BeforeRunTask task = provider.createTask(myRunConfiguration);
@@ -191,8 +243,8 @@ class BeforeRunStepsPanel extends JPanel {
popup.show(button.getPreferredPopupPoint());
}
private List<Key> getActiveProviderKeys() {
List<Key> result = new ArrayList<Key>();
private Set<Key> getActiveProviderKeys() {
Set<Key> result = new HashSet<Key>();
for (BeforeRunTask task : myModel.getItems()) {
result.add(task.getProviderId());
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.execution.impl.ConfigurationSettingsEditorWrapper">
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="myWholePanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="5" bottom="0" right="0"/>
<constraints>
<xy x="124" y="274" width="276" height="150"/>
@@ -30,7 +30,7 @@
</grid>
<component id="c7b94" class="javax.swing.JCheckBox" binding="myCbStoreProjectConfiguration">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ExecutionBundle" key="run.configuration.store.place.option"/>
@@ -45,6 +45,11 @@
</grid>
</constraints>
</vspacer>
<vspacer id="5c515">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</form>
@@ -177,7 +177,7 @@ public abstract class ProjectLevelVcsManager {
@NotNull
public abstract VcsShowConfirmationOption getStandardConfirmation(@NotNull VcsConfiguration.StandardConfirmation option,
@NotNull AbstractVcs vcs);
AbstractVcs vcs);
@NotNull
public abstract VcsShowSettingOption getOrCreateCustomOption(@NotNull String vcsActionName,
@@ -132,6 +132,8 @@ public class PatchApplier<BinaryType extends FilePatch> {
private ApplyPatchStatus myStatus;
private final boolean myShowNotification;
private final boolean mySystemOperation;
private VcsShowConfirmationOption.Value myAddconfirmationvalue;
private VcsShowConfirmationOption.Value myDeleteconfirmationvalue;
public ApplyPatchTask(final boolean showNotification, boolean systemOperation) {
super("", Where.AWT);
@@ -158,17 +160,22 @@ public class PatchApplier<BinaryType extends FilePatch> {
applyStatus = ApplicationManager.getApplication().runReadAction(new Computable<ApplyPatchStatus>() {
public ApplyPatchStatus compute() {
final Ref<ApplyPatchStatus> refStatus = new Ref<ApplyPatchStatus>(ApplyPatchStatus.FAILURE);
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
public void run() {
if (! createFiles()) {
refStatus.set(ApplyPatchStatus.FAILURE);
return;
try {
setConfirmationToDefault();
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
public void run() {
if (! createFiles()) {
refStatus.set(ApplyPatchStatus.FAILURE);
return;
}
addSkippedItems(trigger);
trigger.prepare();
refStatus.set(executeWritable());
}
addSkippedItems(trigger);
trigger.prepare();
refStatus.set(executeWritable());
}
}, VcsBundle.message("patch.apply.command"), null);
}, VcsBundle.message("patch.apply.command"), null);
} finally {
returnConfirmationBack();
}
return refStatus.get();
}
});
@@ -185,6 +192,29 @@ public class PatchApplier<BinaryType extends FilePatch> {
refreshFiles(trigger.getAffected(), context);
}
private void returnConfirmationBack() {
if (mySystemOperation) {
final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject);
final VcsShowConfirmationOption addConfirmation = vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.ADD, null);
addConfirmation.setValue(myAddconfirmationvalue);
final VcsShowConfirmationOption deleteConfirmation = vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.REMOVE, null);
deleteConfirmation.setValue(myDeleteconfirmationvalue);
}
}
private void setConfirmationToDefault() {
if (mySystemOperation) {
final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject);
final VcsShowConfirmationOption addConfirmation = vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.ADD, null);
myAddconfirmationvalue = addConfirmation.getValue();
addConfirmation.setValue(VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY);
final VcsShowConfirmationOption deleteConfirmation = vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.REMOVE, null);
myDeleteconfirmationvalue = deleteConfirmation.getValue();
deleteConfirmation.setValue(VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY);
}
}
public ApplyPatchStatus getStatus() {
return myStatus;
}
@@ -546,7 +546,7 @@ public void addMessageToConsoleWindow(final String message, final TextAttributes
@NotNull
public VcsShowConfirmationOption getStandardConfirmation(@NotNull VcsConfiguration.StandardConfirmation option,
@NotNull AbstractVcs vcs) {
AbstractVcs vcs) {
final VcsShowConfirmationOptionImpl result = getConfirmation(option);
result.addApplicableVcs(vcs);
return result;
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.siyeh.ig.style;
package com.siyeh.ig.controlflow;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
@@ -71,7 +71,14 @@ public class SimplifiableEqualsExpressionInspection extends BaseInspection {
if (operands.length != 2) {
return;
}
final PsiExpression operand = ParenthesesUtils.stripParentheses(operands[1]);
PsiExpression operand = ParenthesesUtils.stripParentheses(operands[1]);
if (operand instanceof PsiPrefixExpression) {
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)operand;
if (!JavaTokenType.EXCL.equals(prefixExpression.getOperationTokenType())) {
return;
}
operand = ParenthesesUtils.stripParentheses(prefixExpression.getOperand());
}
if (!(operand instanceof PsiMethodCallExpression)) {
return;
}
@@ -170,7 +177,15 @@ public class SimplifiableEqualsExpressionInspection extends BaseInspection {
return;
}
final PsiExpression rhs = ParenthesesUtils.stripParentheses(operands[1]);
if (!isEqualsConstant(rhs, variable)) {
if (!(rhs instanceof PsiPrefixExpression)) {
return;
}
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)rhs;
if (!JavaTokenType.EXCL.equals(prefixExpression.getOperationTokenType())) {
return;
}
final PsiExpression operand = ParenthesesUtils.stripParentheses(prefixExpression.getOperand());
if (!isEqualsConstant(operand, variable)) {
return;
}
registerError(lhs);
@@ -226,8 +241,14 @@ public class SimplifiableEqualsExpressionInspection extends BaseInspection {
if (operands.length != 2) {
return null;
}
final PsiExpression lhs = operands[0];
final PsiExpression rhs = operands[1];
final PsiExpression lhs = ParenthesesUtils.stripParentheses(operands[0]);
if (lhs == null) {
return null;
}
final PsiExpression rhs = ParenthesesUtils.stripParentheses(operands[1]);
if (rhs == null) {
return null;
}
if (PsiType.NULL.equals(lhs.getType())) {
if (!(rhs instanceof PsiReferenceExpression)) {
return null;
@@ -0,0 +1,28 @@
package com.siyeh.igtest.controlflow.simplifiable_equals_expression;
public class SimplifiableEqualsExpression {
void foo(String namespace) {
if (namespace != null && namespace.equals("")) {
return;
}
}
void bar(String namespace) {
if (namespace == null || !namespace.equals("")) {
return;
}
}
void baz(Integer i) {
if (i != null && i.equals(1)) {
return;
}
}
void boz(String namespace) {
if (namespace == null || namespace.equals("")) { // don't warn here
return;
}
}
}
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>SimplifiableEqualsExpression.java</file>
<line>12</line>
<entry_point TYPE="method" FQNAME="com.siyeh.igtest.controlflow.simplifiable_equals_expression.SimplifiableEqualsExpression void bar(java.lang.String namespace)" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary 'null' check before 'equals()' call</problem_class>
<description>Unnecessary 'null' check #loc</description>
</problem>
<problem>
<file>SimplifiableEqualsExpression.java</file>
<line>18</line>
<entry_point TYPE="method" FQNAME="com.siyeh.igtest.controlflow.simplifiable_equals_expression.SimplifiableEqualsExpression void baz(java.lang.Integer i)" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary 'null' check before 'equals()' call</problem_class>
<description>Unnecessary 'null' check #loc</description>
</problem>
<problem>
<file>SimplifiableEqualsExpression.java</file>
<line>6</line>
<entry_point TYPE="method" FQNAME="com.siyeh.igtest.controlflow.simplifiable_equals_expression.SimplifiableEqualsExpression void foo(java.lang.String namespace)" />
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary 'null' check before 'equals()' call</problem_class>
<description>Unnecessary 'null' check #loc</description>
</problem>
</problems>
@@ -0,0 +1,11 @@
package com.siyeh.ig.controlflow;
import com.siyeh.ig.IGInspectionTestCase;
public class SimplifiableEqualsExpressionInspectionTest extends IGInspectionTestCase {
public void test() throws Exception {
doTest("com/siyeh/igtest/controlflow/simplifiable_equals_expression",
new SimplifiableEqualsExpressionInspection());
}
}
@@ -23,12 +23,14 @@ import com.android.sdklib.SdkConstants;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import com.intellij.util.text.DateFormatUtil;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidCompilerMessageKind;
import org.jetbrains.android.util.AndroidExecutionUtil;
import org.jetbrains.android.util.AndroidNativeLibData;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -113,32 +115,78 @@ public class AndroidApkBuilder {
@NotNull String[] sourceRoots,
@NotNull String[] externalJars,
@NotNull String[] nativeLibsFolders,
@NotNull Collection<AndroidNativeLibData> additionalNativeLibs,
@NotNull String finalApk,
boolean unsigned,
@NotNull String sdkPath,
@Nullable String customKeystorePath,
@NotNull Condition<File> resourceFilter) throws IOException {
if (unsigned) {
return filterUsingKeystoreMessages(
finalPackage(dexPath, sourceRoots, externalJars, nativeLibsFolders, finalApk, resPackagePath, customKeystorePath, false,
resourceFilter));
}
final Map<AndroidCompilerMessageKind, List<String>> map = new HashMap<AndroidCompilerMessageKind, List<String>>();
final String zipAlignPath = sdkPath + File.separator + AndroidCommonUtils.toolPath(SdkConstants.FN_ZIPALIGN);
boolean withAlignment = new File(zipAlignPath).exists();
String unalignedApk = finalApk + UNALIGNED_SUFFIX;
map.put(ERROR, new ArrayList<String>());
map.put(WARNING, new ArrayList<String>());
File additionalLibsDir = null;
try {
if (additionalNativeLibs.size() > 0) {
additionalLibsDir = FileUtil.createTempDirectory("android_additional_libs", "tmp");
Map<AndroidCompilerMessageKind, List<String>> map2 = filterUsingKeystoreMessages(
finalPackage(dexPath, sourceRoots, externalJars, nativeLibsFolders, withAlignment ? unalignedApk : finalApk, resPackagePath,
customKeystorePath, true, resourceFilter));
map.putAll(map2);
if (!copyNativeLibs(additionalNativeLibs, additionalLibsDir, map)) {
return map;
}
nativeLibsFolders = ArrayUtil.append(nativeLibsFolders, additionalLibsDir.getPath());
}
if (withAlignment && map.get(ERROR).size() == 0) {
map2 = AndroidExecutionUtil.doExecute(zipAlignPath, "-f", "4", unalignedApk, finalApk);
if (unsigned) {
return filterUsingKeystoreMessages(
finalPackage(dexPath, sourceRoots, externalJars, nativeLibsFolders, finalApk, resPackagePath, customKeystorePath, false,
resourceFilter));
}
final String zipAlignPath = sdkPath + File.separator + AndroidCommonUtils.toolPath(SdkConstants.FN_ZIPALIGN);
boolean withAlignment = new File(zipAlignPath).exists();
String unalignedApk = finalApk + UNALIGNED_SUFFIX;
Map<AndroidCompilerMessageKind, List<String>> map2 = filterUsingKeystoreMessages(
finalPackage(dexPath, sourceRoots, externalJars, nativeLibsFolders, withAlignment ? unalignedApk : finalApk, resPackagePath,
customKeystorePath, true, resourceFilter));
map.putAll(map2);
if (withAlignment && map.get(ERROR).size() == 0) {
map2 = AndroidExecutionUtil.doExecute(zipAlignPath, "-f", "4", unalignedApk, finalApk);
map.putAll(map2);
}
return map;
}
return map;
finally {
if (additionalLibsDir != null) {
FileUtil.delete(additionalLibsDir);
}
}
}
private static boolean copyNativeLibs(@NotNull Collection<AndroidNativeLibData> libs,
@NotNull File targetDir,
@NotNull Map<AndroidCompilerMessageKind, List<String>> map) throws IOException {
for (AndroidNativeLibData lib : libs) {
final String path = lib.getPath();
final File srcFile = new File(path);
if (!srcFile.exists()) {
map.get(WARNING).add("File not found: " + FileUtil.toSystemDependentName(path) + ". The native library won't be placed into APK");
continue;
}
final File dstDir = new File(targetDir, lib.getArchitecture());
final File dstFile = new File(dstDir, lib.getTargetFileName());
if (dstFile.exists()) {
map.get(WARNING).add("Duplicate native library " + dstFile.getName() + "; " + dstFile.getPath() + " already exists");
continue;
}
if (!dstDir.mkdirs()) {
map.get(ERROR).add("Cannot create directory: " + FileUtil.toSystemDependentName(dstDir.getPath()));
continue;
}
FileUtil.copy(srcFile, dstFile);
}
return map.get(ERROR).size() == 0;
}
private static Map<AndroidCompilerMessageKind, List<String>> finalPackage(@NotNull String dexPath,
@@ -75,7 +75,13 @@ public class AndroidCommonUtils {
public static final ResourceType[] ID_PROVIDING_RESOURCE_TYPES = new ResourceType[] {
ResourceType.LAYOUT, ResourceType.MENU
};
@NonNls public static final String INCLUDE_SYSTEM_PROGUARD_FILE_ELEMENT_NAME = "includeSystemProguardFile";
@NonNls public static final String ADDITIONAL_NATIVE_LIBS_ELEMENT = "additionalNativeLibs";
@NonNls public static final String ITEM_ELEMENT = "item";
@NonNls public static final String ARCHITECTURE_ATTRIBUTE = "architecture";
@NonNls public static final String URL_ATTRIBUTE = "url";
@NonNls public static final String TARGET_FILE_NAME_ATTRIBUTE = "targetFileName";
private static final String[] TEST_CONFIGURATION_TYPE_IDS =
{"JUnit", "TestNG", "ScalaTestRunConfiguration", "SpecsRunConfiguration", "Specs2RunConfiguration"};
@@ -0,0 +1,55 @@
package org.jetbrains.android.util;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidNativeLibData {
private final String myPath;
private final String myArchitecture;
private final String myTargetFileName;
public AndroidNativeLibData(@NotNull String architecture, @NotNull String path, @NotNull String targetFileName) {
myPath = path;
myArchitecture = architecture;
myTargetFileName = targetFileName;
}
@NotNull
public String getPath() {
return myPath;
}
@NotNull
public String getArchitecture() {
return myArchitecture;
}
@NotNull
public String getTargetFileName() {
return myTargetFileName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AndroidNativeLibData lib = (AndroidNativeLibData)o;
if (!myArchitecture.equals(lib.myArchitecture)) return false;
if (!myTargetFileName.equals(lib.myTargetFileName)) return false;
if (!myPath.equals(lib.myPath)) return false;
return true;
}
@Override
public int hashCode() {
int result = myPath.hashCode();
result = 31 * result + myArchitecture.hashCode();
result = 31 * result + myTargetFileName.hashCode();
return result;
}
}
@@ -1,11 +1,14 @@
package org.jetbrains.jps.android;
import org.jetbrains.android.util.AndroidNativeLibData;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.incremental.storage.ValidityState;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eugene.Kudelevsky
@@ -13,15 +16,28 @@ import java.io.IOException;
public class AndroidApkBuilderConfigState implements ValidityState {
private final String myOutputApkPath;
private final String myCustomKeystorePath;
private final List<AndroidNativeLibData> myAdditionalNativeLibs;
public AndroidApkBuilderConfigState(@NotNull String outputApkPath, @NotNull String customKeystorePath) {
public AndroidApkBuilderConfigState(@NotNull String outputApkPath,
@NotNull String customKeystorePath,
@NotNull List<AndroidNativeLibData> additionalNativeLibs) {
myOutputApkPath = outputApkPath;
myCustomKeystorePath = customKeystorePath;
myAdditionalNativeLibs = additionalNativeLibs;
}
public AndroidApkBuilderConfigState(DataInput in) throws IOException {
myOutputApkPath = in.readUTF();
myCustomKeystorePath = in.readUTF();
final int additionalNativeLibsCount = in.readInt();
myAdditionalNativeLibs = new ArrayList<AndroidNativeLibData>(additionalNativeLibsCount);
for (int i = 0; i < additionalNativeLibsCount; i++) {
final String architecture = in.readUTF();
final String path = in.readUTF();
final String targetFileName = in.readUTF();
myAdditionalNativeLibs.add(new AndroidNativeLibData(architecture, path, targetFileName));
}
}
@Override
@@ -31,12 +47,20 @@ public class AndroidApkBuilderConfigState implements ValidityState {
}
final AndroidApkBuilderConfigState apkBuilderConfigState = (AndroidApkBuilderConfigState)otherState;
return apkBuilderConfigState.myOutputApkPath.equals(myOutputApkPath) &&
apkBuilderConfigState.myCustomKeystorePath.equals(myCustomKeystorePath);
apkBuilderConfigState.myCustomKeystorePath.equals(myCustomKeystorePath) &&
apkBuilderConfigState.myAdditionalNativeLibs.equals(myAdditionalNativeLibs);
}
@Override
public void save(DataOutput out) throws IOException {
out.writeUTF(myOutputApkPath);
out.writeUTF(myCustomKeystorePath);
out.writeInt(myAdditionalNativeLibs.size());
for (AndroidNativeLibData lib : myAdditionalNativeLibs) {
out.writeUTF(lib.getArchitecture());
out.writeUTF(lib.getPath());
out.writeUTF(lib.getTargetFileName());
}
}
}
@@ -1,6 +1,7 @@
package org.jetbrains.jps.android
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.android.util.AndroidNativeLibData
import org.jetbrains.jps.Module
import org.jetbrains.jps.idea.Facet
@@ -33,6 +34,8 @@ class AndroidFacet extends Facet {
boolean runProguard
boolean includeSystemProguardCfgFile
List<AndroidNativeLibData> additionalNativeLibs
AndroidFacet(Module module, String name) {
this.module = module
this.name = name;
@@ -1,6 +1,7 @@
package org.jetbrains.jps.android
import org.jetbrains.android.util.AndroidCommonUtils
import org.jetbrains.android.util.AndroidNativeLibData
import org.jetbrains.jps.MacroExpander
import org.jetbrains.jps.Module
import org.jetbrains.jps.idea.Facet
@@ -20,12 +21,27 @@ class AndroidFacetType extends FacetTypeService {
@Override
Facet createFacet(Module module, String name, Node facetConfiguration, MacroExpander macroExpander) {
def facet = new AndroidFacet(module, name);
facet.additionalNativeLibs = new ArrayList<AndroidNativeLibData>()
facetConfiguration.each {Node child ->
if (AndroidCommonUtils.INCLUDE_SYSTEM_PROGUARD_FILE_ELEMENT_NAME.equals(child.name())) {
facet.includeSystemProguardCfgFile = Boolean.parseBoolean((String)child.text())
}
if (AndroidCommonUtils.ADDITIONAL_NATIVE_LIBS_ELEMENT.equals(child.name())) {
child.each {Node nativeLibItem ->
final architecture = nativeLibItem.get("@" + AndroidCommonUtils.ARCHITECTURE_ATTRIBUTE)
final url = nativeLibItem.get("@" + AndroidCommonUtils.URL_ATTRIBUTE)
final targetFileName = nativeLibItem.get("@" + AndroidCommonUtils.TARGET_FILE_NAME_ATTRIBUTE)
if (architecture != null && url != null && targetFileName != null) {
facet.additionalNativeLibs.add(new AndroidNativeLibData((String)architecture,
IdeaProjectLoadingUtil.pathFromUrl((String)url),
(String)targetFileName))
}
}
}
String value = child."@value"
switch (child."@name") {
@@ -10,6 +10,7 @@ import org.jetbrains.android.compiler.tools.AndroidApkBuilder;
import org.jetbrains.android.compiler.tools.AndroidApt;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidCompilerMessageKind;
import org.jetbrains.android.util.AndroidNativeLibData;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -139,9 +140,11 @@ public class AndroidPackagingBuilder extends ProjectLevelBuilder {
@NotNull Module module,
@NotNull AndroidFileSetStorage storage,
@Nullable AndroidFileSetState state) throws IOException {
final AndroidFileSetState savedState = storage.getState(module.getName());
if (context.isMake() && savedState != null && savedState.equalsTo(state)) {
return true;
if (context.isMake()) {
final AndroidFileSetState savedState = storage.getState(module.getName());
if (savedState != null && savedState.equalsTo(state)) {
return true;
}
}
final AndroidFacet facet = AndroidJpsUtil.getFacet(module);
@@ -362,27 +365,31 @@ public class AndroidPackagingBuilder extends ProjectLevelBuilder {
final String classesDexFilePath = classesDexFile.getPath();
final String[] externalJars = ArrayUtil.toStringArray(externalJarsSet);
// currently including native libraries through pom.xml doesn't work when jps compilation is used, MAVEN_REPOSITORY url macros needed
final List<AndroidNativeLibData> additionalNativeLibs = facet.getAdditionalNativeLibs();
final AndroidFileSetState currentFileSetState =
buildCurrentApkBuilderState(context.getProject(), resPackagePath, classesDexFilePath, nativeLibDirs,
sourceRoots, externalJars, release);
buildCurrentApkBuilderState(context.getProject(), resPackagePath, classesDexFilePath, nativeLibDirs, sourceRoots,
externalJars, release);
final AndroidApkBuilderConfigState currentApkBuilderConfigState =
new AndroidApkBuilderConfigState(outputApkPath, customKeyStorePath);
new AndroidApkBuilderConfigState(outputApkPath, customKeyStorePath, additionalNativeLibs);
final AndroidFileSetState savedApkFileSetState = apkFileSetStorage.getState(module.getName());
final AndroidApkBuilderConfigState savedApkBuilderConfigState = apkBuilderConfigStateStorage.getState(module.getName());
if (context.isMake()) {
final AndroidFileSetState savedApkFileSetState = apkFileSetStorage.getState(module.getName());
final AndroidApkBuilderConfigState savedApkBuilderConfigState = apkBuilderConfigStateStorage.getState(module.getName());
if (context.isMake() &&
currentFileSetState.equalsTo(savedApkFileSetState) &&
currentApkBuilderConfigState.equalsTo(savedApkBuilderConfigState)) {
return true;
if (currentFileSetState.equalsTo(savedApkFileSetState) &&
currentApkBuilderConfigState.equalsTo(savedApkBuilderConfigState)) {
return true;
}
}
context
.processMessage(new ProgressMessage(AndroidJpsBundle.message("android.jps.progress.packaging", AndroidJpsUtil.getApkName(module))));
final Map<AndroidCompilerMessageKind, List<String>> messages = AndroidApkBuilder
.execute(resPackagePath, classesDexFilePath, sourceRoots, externalJars, nativeLibDirs, outputApkPath,
release, sdkPath, customKeyStorePath, new MyExcludedSourcesFilter(context.getProject()));
.execute(resPackagePath, classesDexFilePath, sourceRoots, externalJars, nativeLibDirs, additionalNativeLibs,
outputApkPath, release, sdkPath, customKeyStorePath, new MyExcludedSourcesFilter(context.getProject()));
AndroidJpsUtil.addMessages(context, messages, BUILDER_NAME);
final boolean success = messages.get(AndroidCompilerMessageKind.ERROR).isEmpty();
@@ -30,4 +30,16 @@ class AndroidSdk extends JavaSdk {
def javaSdk = project.sdks[javaSdkName]
return javaSdk instanceof JavaSdkImpl ? javaSdk.getJavaExecutable() : null
}
@Override
String getHomePath() {
def javaSdk = project.sdks[javaSdkName]
return javaSdk instanceof JavaSdkImpl ? javaSdk.getHomePath() : null
}
@Override
String getVersion() {
def javaSdk = project.sdks[javaSdkName]
return javaSdk instanceof JavaSdkImpl ? javaSdk.getVersion() : null
}
}
@@ -36,6 +36,7 @@ import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidNativeLibData;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -157,8 +158,9 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
boolean generateSignedApk,
boolean releaseBuild,
String customKeystorePath) {
AptPackagingItem item =
new AptPackagingItem(sdkPath, manifestFile, resPackagePath, outputPath, generateSignedApk, releaseBuild, module, customKeystorePath);
final AptPackagingItem item =
new AptPackagingItem(sdkPath, manifestFile, resPackagePath, outputPath, generateSignedApk, releaseBuild, module, customKeystorePath,
facet.getConfiguration().getAdditionalNativeLibraries());
item.setNativeLibsFolders(collectNativeLibsFolders(facet));
item.setClassesDexPath(classesDexPath);
item.setSourceRoots(sourceRoots);
@@ -239,8 +241,8 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
final Project project = context.getProject();
final Map<CompilerMessageCategory, List<String>> messages = AndroidCompileUtil.toCompilerMessageCategoryKeys(
AndroidApkBuilder.execute(resPackagePath, item.getClassesDexPath(), sourceRoots, externalLibPaths,
nativeLibsFolders, finalPath, unsigned, item.mySdkPath, item.getCustomKeystorePath(),
AndroidApkBuilder.execute(resPackagePath, item.getClassesDexPath(), sourceRoots, externalLibPaths, nativeLibsFolders,
item.getAdditionalNativeLibs(), finalPath, unsigned, item.mySdkPath, item.getCustomKeystorePath(),
new ExcludedSourcesFilter(project)));
AndroidCompileUtil.addMessages(context, messages);
@@ -298,6 +300,7 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
private final String myFinalPath;
private String myClassesDexPath;
private VirtualFile[] myNativeLibsFolders;
private final List<AndroidNativeLibData> myAdditionalNativeLibs;
private VirtualFile[] mySourceRoots;
private VirtualFile[] myExternalLibraries;
private final boolean myGenerateUnsigendApk;
@@ -313,7 +316,8 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
boolean generateUnsigendApk,
boolean releaseBuild,
@NotNull Module module,
@Nullable String customKeystorePath) {
@Nullable String customKeystorePath,
@NotNull List<AndroidNativeLibData> additionalNativeLibs) {
mySdkPath = sdkPath;
myManifestFile = manifestFile;
myResPackagePath = resPackagePath;
@@ -322,6 +326,7 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
myReleaseBuild = releaseBuild;
myModule = module;
myCustomKeystorePath = customKeystorePath;
myAdditionalNativeLibs = additionalNativeLibs;
}
@NotNull
@@ -349,6 +354,11 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
return myNativeLibsFolders;
}
@NotNull
public List<AndroidNativeLibData> getAdditionalNativeLibs() {
return myAdditionalNativeLibs;
}
@NotNull
public VirtualFile[] getSourceRoots() {
return mySourceRoots;
@@ -383,12 +393,14 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
@Nullable
public ValidityState getValidityState() {
return new MyValidityState(myModule.getProject(), myResPackagePath, myClassesDexPath, myFinalPath, myGenerateUnsigendApk,
myReleaseBuild, mySourceRoots, myExternalLibraries, myNativeLibsFolders, myCustomKeystorePath);
myReleaseBuild, mySourceRoots, myExternalLibraries, myNativeLibsFolders, myCustomKeystorePath,
myAdditionalNativeLibs);
}
}
private static class MyValidityState implements ValidityState {
private final Map<String, Long> myResourceTimestamps = new HashMap<String, Long>();
private final Map<AndroidNativeLibData, Long> myAdditionalNativeLibs = new HashMap<AndroidNativeLibData, Long>();
private final String myApkPath;
private final boolean myGenerateUnsignedApk;
private final boolean myReleaseBuild;
@@ -405,6 +417,15 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
myReleaseBuild = is.readBoolean();
myApkPath = is.readUTF();
myCustomKeystorePath = CompilerIOUtil.readString(is);
size = is.readInt();
for (int i = 0; i < size; i++) {
final String architecture = is.readUTF();
final String path = is.readUTF();
final String targetFileName = is.readUTF();
final long timestamp = is.readLong();
myAdditionalNativeLibs.put(new AndroidNativeLibData(architecture, path, targetFileName), timestamp);
}
}
MyValidityState(Project project,
@@ -416,7 +437,8 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
VirtualFile[] sourceRoots,
VirtualFile[] externalLibs,
VirtualFile[] nativeLibFolders,
String customKeystorePath) {
String customKeystorePath,
List<AndroidNativeLibData> additionalNativeLibs) {
myResourceTimestamps.put(FileUtil.toSystemIndependentName(resPackagePath), new File(resPackagePath).lastModified());
myResourceTimestamps.put(FileUtil.toSystemIndependentName(classesDexPath), new File(classesDexPath).lastModified());
myApkPath = apkPath;
@@ -445,6 +467,10 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
for (File nativeLib : nativeLibs) {
myResourceTimestamps.put(FileUtil.toSystemIndependentName(nativeLib.getPath()), nativeLib.lastModified());
}
for (AndroidNativeLibData lib : additionalNativeLibs) {
final String path = lib.getPath();
myAdditionalNativeLibs.put(lib, new File(path).lastModified());
}
}
@Override
@@ -457,7 +483,8 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
mvs.myReleaseBuild == myReleaseBuild &&
mvs.myResourceTimestamps.equals(myResourceTimestamps) &&
mvs.myApkPath.equals(myApkPath) &&
mvs.myCustomKeystorePath.equals(myCustomKeystorePath);
mvs.myCustomKeystorePath.equals(myCustomKeystorePath) &&
mvs.myAdditionalNativeLibs.equals(myAdditionalNativeLibs);
}
@Override
@@ -471,6 +498,15 @@ public class AndroidPackagingCompiler implements PackagingCompiler {
out.writeBoolean(myReleaseBuild);
out.writeUTF(myApkPath);
CompilerIOUtil.writeString(myCustomKeystorePath, out);
out.writeInt(myAdditionalNativeLibs.size());
for (Map.Entry<AndroidNativeLibData, Long> entry : myAdditionalNativeLibs.entrySet()) {
final AndroidNativeLibData lib = entry.getKey();
out.writeUTF(lib.getArchitecture());
out.writeUTF(lib.getPath());
out.writeUTF(lib.getTargetFileName());
out.writeLong(entry.getValue());
}
}
}
}
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import org.jdom.Element;
import org.jetbrains.android.compiler.AndroidCompileUtil;
@@ -36,12 +37,14 @@ import org.jetbrains.android.sdk.AndroidSdkAdditionalData;
import org.jetbrains.android.sdk.AndroidSdkData;
import org.jetbrains.android.sdk.AndroidSdkType;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.AndroidNativeLibData;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
@@ -89,6 +92,8 @@ public class AndroidFacetConfiguration implements FacetConfiguration {
private boolean myIncludeSystemProguardCfgPath = true;
private List<AndroidNativeLibData> myAdditionalNativeLibraries = Collections.emptyList();
private AndroidFacet myFacet = null;
public void init(@NotNull Module module, @NotNull VirtualFile contentRoot) {
@@ -153,6 +158,22 @@ public class AndroidFacetConfiguration implements FacetConfiguration {
DefaultJDOMExternalizer.readExternal(this, element);
readResOverlayFolders(element);
final Element additionalNativeLibsElement = element.getChild(AndroidCommonUtils.ADDITIONAL_NATIVE_LIBS_ELEMENT);
myAdditionalNativeLibraries = new ArrayList<AndroidNativeLibData>();
if (additionalNativeLibsElement != null) {
for (Object child : additionalNativeLibsElement.getChildren()) {
final Element childElement = (Element)child;
final String architecture = childElement.getAttributeValue(AndroidCommonUtils.ARCHITECTURE_ATTRIBUTE);
final String url = childElement.getAttributeValue(AndroidCommonUtils.URL_ATTRIBUTE);
final String targetFileName = childElement.getAttributeValue(AndroidCommonUtils.TARGET_FILE_NAME_ATTRIBUTE);
if (url != null && architecture != null && targetFileName != null) {
myAdditionalNativeLibraries.add(new AndroidNativeLibData(architecture, VfsUtil.urlToPath(url), targetFileName));
}
}
}
final Element includeSystemProguardFile = element.getChild(AndroidCommonUtils.INCLUDE_SYSTEM_PROGUARD_FILE_ELEMENT_NAME);
if (includeSystemProguardFile != null) {
final String includeSystemProguardFileValue = includeSystemProguardFile.getValue();
@@ -172,6 +193,17 @@ public class AndroidFacetConfiguration implements FacetConfiguration {
final Element includeSystemProguerdFile = new Element(AndroidCommonUtils.INCLUDE_SYSTEM_PROGUARD_FILE_ELEMENT_NAME);
includeSystemProguerdFile.setText(Boolean.toString(myIncludeSystemProguardCfgPath));
element.addContent(includeSystemProguerdFile);
final Element additionalNativeLibs = new Element(AndroidCommonUtils.ADDITIONAL_NATIVE_LIBS_ELEMENT);
for (AndroidNativeLibData lib : myAdditionalNativeLibraries) {
final Element item = new Element(AndroidCommonUtils.ITEM_ELEMENT);
item.setAttribute(AndroidCommonUtils.ARCHITECTURE_ATTRIBUTE, lib.getArchitecture());
item.setAttribute(AndroidCommonUtils.URL_ATTRIBUTE, VfsUtil.pathToUrl(lib.getPath()));
item.setAttribute(AndroidCommonUtils.TARGET_FILE_NAME_ATTRIBUTE, lib.getTargetFileName());
additionalNativeLibs.addContent(item);
}
element.addContent(additionalNativeLibs);
}
private void readResOverlayFolders(final Element element) throws InvalidDataException {
@@ -205,4 +237,13 @@ public class AndroidFacetConfiguration implements FacetConfiguration {
public void setIncludeSystemProguardCfgPath(boolean includeSystemProguardCfgPath) {
myIncludeSystemProguardCfgPath = includeSystemProguardCfgPath;
}
@NotNull
public List<AndroidNativeLibData> getAdditionalNativeLibraries() {
return myAdditionalNativeLibraries;
}
public void setAdditionalNativeLibraries(@NotNull List<AndroidNativeLibData> additionalNativeLibraries) {
myAdditionalNativeLibraries = additionalNativeLibraries;
}
}
@@ -45,7 +45,9 @@ import org.jetbrains.android.facet.AndroidFacetConfiguration;
import org.jetbrains.android.facet.AndroidFacetType;
import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.sdk.*;
import org.jetbrains.android.util.AndroidNativeLibData;
import org.jetbrains.android.util.AndroidUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.importing.FacetImporter;
@@ -71,6 +73,7 @@ public abstract class AndroidFacetImporterBase extends FacetImporter<AndroidFace
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.maven.AndroidFacetImporterBase");
private static final Key<Boolean> MODULE_IMPORTED = Key.create("ANDROID_NEWLY_CREATED_KEY");
@NonNls private static final String DEFAULT_NATIVE_ARCHITECTURE = "armeabi";
public AndroidFacetImporterBase(@NotNull String pluginId) {
super("com.jayway.maven.plugins.android.generation2", pluginId, FacetType.findInstance(AndroidFacetType.class), "Android");
@@ -137,6 +140,37 @@ public abstract class AndroidFacetImporterBase extends FacetImporter<AndroidFace
postTasks.add(new MyDeleteObsoleteApklibModulesTask(module.getProject(), mavenProject, mavenTree));
}
private void importNativeDependencies(@NotNull AndroidFacet facet, @NotNull MavenProject mavenProject, @NotNull String moduleDirPath) {
final List<AndroidNativeLibData> additionalNativeLibs = new ArrayList<AndroidNativeLibData>();
final String localRepository = MavenProjectsManager.getInstance(facet.getModule().getProject()).getLocalRepository().getPath();
String defaultArchitecture = getPathFromConfig(facet.getModule(), mavenProject, moduleDirPath,
"nativeLibrariesDependenciesHardwareArchitectureDefault", false, true);
if (defaultArchitecture == null) {
defaultArchitecture = DEFAULT_NATIVE_ARCHITECTURE;
}
final String forcedArchitecture = getPathFromConfig(facet.getModule(), mavenProject, moduleDirPath,
"nativeLibrariesDependenciesHardwareArchitectureOverride", false, true);
for (MavenArtifact depArtifact : mavenProject.getDependencies()) {
if (AndroidMavenUtil.SO_PACKAGING_AND_DEPENDENCY_TYPE.equals(depArtifact.getType())) {
final String architecture;
if (forcedArchitecture != null) {
architecture = forcedArchitecture;
}
else {
final String classifier = depArtifact.getClassifier();
architecture = classifier != null ? classifier : defaultArchitecture;
}
final String path = FileUtil.toSystemIndependentName(localRepository + '/' + depArtifact.getRelativePath());
final String artifactId = depArtifact.getArtifactId();
final String targetFileName = artifactId.startsWith("lib") ? artifactId + ".so" : "lib" + artifactId + ".so";
additionalNativeLibs.add(new AndroidNativeLibData(architecture, path, targetFileName));
}
}
facet.getConfiguration().setAdditionalNativeLibraries(additionalNativeLibs);
}
private static boolean hasApklibDependencies(@NotNull MavenProject mavenProject) {
for (MavenArtifact depArtifact : mavenProject.getDependencies()) {
if (AndroidMavenUtil.APKLIB_DEPENDENCY_AND_PACKAGING_TYPE.equals(depArtifact.getType())) {
@@ -676,6 +710,9 @@ public abstract class AndroidFacetImporterBase extends FacetImporter<AndroidFace
private void configurePaths(AndroidFacet facet, MavenProject project) {
Module module = facet.getModule();
String moduleDirPath = AndroidRootUtil.getModuleDirPath(module);
if (moduleDirPath == null) {
return;
}
AndroidFacetConfiguration configuration = facet.getConfiguration();
String resFolderRelPath = getPathFromConfig(module, project, moduleDirPath, "resourceDirectory", true, true);
@@ -740,6 +777,8 @@ public abstract class AndroidFacetImporterBase extends FacetImporter<AndroidFace
if (nativeLibsFolderRelPath != null && isFullyResolved(nativeLibsFolderRelPath)) {
configuration.LIBS_FOLDER_RELATIVE_PATH = '/' + nativeLibsFolderRelPath;
}
importNativeDependencies(facet, project, moduleDirPath);
}
private static boolean isFullyResolved(@NotNull String s) {
@@ -35,6 +35,7 @@ public class AndroidMavenUtil {
@NonNls public static final String APKSOURCES_DEPENDENCY_TYPE = "apksources";
@NonNls public static final String APKLIB_DEPENDENCY_AND_PACKAGING_TYPE = "apklib";
@NonNls public static final String SO_PACKAGING_AND_DEPENDENCY_TYPE = "so";
@NonNls public static final String APK_PACKAGING_TYPE = "apk";
@NonNls public static final String APK_LIB_ARTIFACT_SOURCE_ROOT = "src";
@@ -20,12 +20,16 @@ import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.UsageSearchContext;
import com.intellij.psi.search.searches.MethodReferencesSearch;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.MixinMemberContributor;
/**
* author ven
@@ -39,13 +43,24 @@ public class AccessorMethodReferencesSearcher extends QueryExecutorBase<PsiRefer
@Override
public void processQuery(@NotNull MethodReferencesSearch.SearchParameters queryParameters, @NotNull Processor<PsiReference> consumer) {
final PsiMethod method = queryParameters.getMethod();
final String propertyName = GroovyPropertyUtils.getPropertyName(method);
final String propertyName;
if (MixinMemberContributor.isCategoryMethod(method, null)) {
final GrGdkMethod cat = GrGdkMethodImpl.createGdkMethod(method, false);
propertyName = GroovyPropertyUtils.getPropertyName((PsiMethod)cat);
}
else {
propertyName = GroovyPropertyUtils.getPropertyName(method);
}
if (propertyName == null) return;
queryParameters.getOptimizer().searchWord(propertyName, PsiUtil.restrictScopeToGroovyFiles(queryParameters.getScope()), UsageSearchContext.IN_CODE, true, method);
final SearchScope onlyGroovyFiles = PsiUtil.restrictScopeToGroovyFiles(queryParameters.getScope());
queryParameters.getOptimizer().searchWord(propertyName, onlyGroovyFiles, UsageSearchContext.IN_CODE, true, method);
if (!GroovyPropertyUtils.isPropertyName(propertyName)) {
queryParameters.getOptimizer().searchWord(StringUtil.decapitalize(propertyName), PsiUtil.restrictScopeToGroovyFiles(queryParameters.getScope()), UsageSearchContext.IN_CODE, true, method);
queryParameters.getOptimizer().searchWord(StringUtil.decapitalize(propertyName), onlyGroovyFiles, UsageSearchContext.IN_CODE, true, method);
}
}
@@ -47,7 +47,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.impl.*;
@@ -171,21 +170,17 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
}
}
final boolean isPropertyName = GroovyPropertyUtils.isPropertyName(name);
final boolean isLValue = PsiUtil.isLValue(this);
String[] accessorNames = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name);
List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
for (String accessorName : accessorNames) {
AccessorResolverProcessor accessorResolver =
new AccessorResolverProcessor(accessorName, this, !isLValue, false, getThisType(), getTypeArguments());
AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(accessorName, name, this, !isLValue, false, getThisType(), getTypeArguments());
GrReferenceResolveUtil.resolveImpl(accessorResolver, this);
final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one correct candidate
if (candidates.length > 0 && candidates[candidates.length - 1].isStaticsOK()) {
if (isPropertyName || isCorrectRefNameForResolved(candidates, name)) {
if (candidates.length == 1) return candidates;
return new GroovyResolveResult[]{candidates[candidates.length - 1]};
}
final GroovyResolveResult[] candidates = accessorResolver.getCandidates();
//can be only one correct candidate or some incorrect
if (candidates.length == 1 && candidates[0].isStaticsOK() && candidates[0].isAccessible()) {
return candidates;
}
else {
ContainerUtil.addAll(accessorResults, candidates);
@@ -202,17 +197,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
return GroovyResolveResult.EMPTY_ARRAY;
}
/**
* It is allowed to use capitalized property name if the field is capitalized
*/
private static boolean isCorrectRefNameForResolved(GroovyResolveResult[] candidates, String name) {
assert !GroovyPropertyUtils.isPropertyName(name);
PsiElement element = candidates[candidates.length - 1].getElement();
if (!(element instanceof GrAccessorMethod)) return false;
String fname = ((GrAccessorMethod)element).getProperty().getName();
return name.equals(fname);
}
public GroovyResolveResult[] getCallVariants(GrExpression upToArgument) {
return resolveMethodOrProperty(true, upToArgument, true);
@@ -301,7 +286,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
//search for getters
for (String getterName : GroovyPropertyUtils.suggestGettersName(name)) {
AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, this, true, genericsMatter, getThisType(), getTypeArguments());
AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, name, this, true, genericsMatter, getThisType(), getTypeArguments());
GrReferenceResolveUtil.resolveImpl(getterResolver, this);
final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate
if (!allVariants && candidates.length == 1) {
@@ -97,7 +97,7 @@ public class GroovyPropertyUtils {
return findPropertySetter(fromText.getType(), propertyName, context);
}
final AccessorResolverProcessor processor = new AccessorResolverProcessor(setterName, context, false);
final AccessorResolverProcessor processor = new AccessorResolverProcessor(setterName, propertyName, context, false);
ResolveUtil.processAllDeclarations(type, processor, ResolveState.initial(), context);
final GroovyResolveResult[] setterCandidates = processor.getCandidates();
return PsiImplUtil.extractUniqueElement(setterCandidates);
@@ -220,7 +220,12 @@ public class GroovyPropertyUtils {
if (method.getName().startsWith(IS_PREFIX) && !PsiType.BOOLEAN.equals(method.getReturnType())) {
return false;
}
return (propertyName == null || propertyName.equals(getPropertyNameByGetter(method))) && method.getReturnType() != PsiType.VOID;
if (method.getReturnType() == PsiType.VOID) return false;
if (propertyName == null) return true;
final String byGetter = getPropertyNameByGetter(method);
return propertyName.equals(byGetter) || (!isPropertyName(byGetter) && propertyName.equals(
getPropertyNameByGetterName(method.getName(), PsiType.BOOLEAN.equals(method.getReturnType()))));
}
public static boolean isSimplePropertySetter(PsiMethod method) {
@@ -231,7 +236,10 @@ public class GroovyPropertyUtils {
if (method == null || method.isConstructor()) return false;
if (method.getParameterList().getParametersCount() != 1) return false;
if (!isSetterName(method.getName())) return false;
return propertyName == null || propertyName.equals(getPropertyNameBySetter(method));
if (propertyName==null) return true;
final String bySetter = getPropertyNameBySetter(method);
return propertyName.equals(bySetter) || (!isPropertyName(bySetter) && propertyName.equals(getPropertyNameBySetterName(method.getName())));
}
@Nullable
@@ -19,6 +19,7 @@ import com.intellij.psi.*;
import com.intellij.psi.scope.DelegatingScopeProcessor;
import com.intellij.psi.scope.PsiScopeProcessor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer;
@@ -38,9 +39,9 @@ import java.util.List;
public class MixinMemberContributor extends NonCodeMembersContributor {
@Override
public void processDynamicElements(@NotNull final PsiType qualifierType,
PsiScopeProcessor processor,
GroovyPsiElement place,
ResolveState state) {
@NotNull PsiScopeProcessor processor,
@NotNull GroovyPsiElement place,
@NotNull ResolveState state) {
if (!(qualifierType instanceof PsiClassType)) return;
if (isInAnnotation(place)) return;
final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)qualifierType).resolveGenerics();
@@ -92,16 +93,16 @@ public class MixinMemberContributor extends NonCodeMembersContributor {
return result;
}
private static boolean isCategoryMethod(PsiElement element, PsiType qualifierType) {
public static boolean isCategoryMethod(@Nullable PsiElement element, @Nullable PsiType qualifierType) {
if (!(element instanceof PsiMethod)) return false;
if (!((PsiMethod)element).hasModifierProperty(PsiModifier.STATIC)) return false;
final PsiParameter[] parameters = ((PsiMethod)element).getParameterList().getParameters();
if (parameters.length == 0) return false;
final PsiParameter selfParam = parameters[0];
final PsiType selfType = selfParam.getType();
if (qualifierType == null) return true;
final PsiType selfType = parameters[0].getType();
return TypesUtil.isAssignable(selfType, qualifierType, element.getManager(), element.getResolveScope());
}
@@ -651,7 +651,7 @@ public class ResolveUtil {
//search for getters
for (String getterName : GroovyPropertyUtils.suggestGettersName(methodName)) {
AccessorResolverProcessor getterResolver =
new AccessorResolverProcessor(getterName, place, true, false, thisType, PsiType.EMPTY_ARRAY);
new AccessorResolverProcessor(getterName, methodName, place, true, false, thisType, PsiType.EMPTY_ARRAY);
processAllDeclarations(thisType, getterResolver, ResolveState.initial(), place);
final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate
final List<GroovyResolveResult> applicable = new ArrayList<GroovyResolveResult>();
@@ -19,27 +19,33 @@ import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
/**
* @author Maxim.Medvedev
*/
public class AccessorResolverProcessor extends ResolverProcessor {
public class AccessorResolverProcessor extends MethodResolverProcessor {
private final String myPropertyName;
private final boolean mySearchForGetter;
private final SubstitutorComputer mySubstitutorComputer;
public AccessorResolverProcessor(String name, GroovyPsiElement place, boolean searchForGetter) {
this(name, place, searchForGetter, false, null, PsiType.EMPTY_ARRAY);
public AccessorResolverProcessor(String accessorName, String propertyName, GroovyPsiElement place, boolean searchForGetter) {
this(accessorName, propertyName, place, searchForGetter, false, null, PsiType.EMPTY_ARRAY);
}
public AccessorResolverProcessor(String name,
public AccessorResolverProcessor(String accessorName,
String propertyName,
GroovyPsiElement place,
boolean searchForGetter,
boolean byShape,
@Nullable PsiType thisType,
@NotNull PsiType[] typeArguments) {
super(name, RESOLVE_KINDS_METHOD, place, PsiType.EMPTY_ARRAY);
super(accessorName, place, false, thisType, null, typeArguments, false, byShape);
myPropertyName = propertyName;
mySearchForGetter = searchForGetter;
mySubstitutorComputer = byShape ? null : new SubstitutorComputer(thisType, PsiType.EMPTY_ARRAY, typeArguments, false, place) {
@Override
@@ -51,12 +57,12 @@ public class AccessorResolverProcessor extends ResolverProcessor {
public boolean execute(PsiElement element, ResolveState state) {
if (mySearchForGetter) {
if (element instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyGetter((PsiMethod)element, null)) {
if (element instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertyGetter((PsiMethod)element, myPropertyName)) {
return addAccessor((PsiMethod)element, state);
}
}
else {
if (element instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertySetter((PsiMethod)element, null)) {
if (element instanceof PsiMethod && GroovyPropertyUtils.isSimplePropertySetter((PsiMethod)element, myPropertyName)) {
return addAccessor((PsiMethod)element, state);
}
}
@@ -73,7 +79,29 @@ public class AccessorResolverProcessor extends ResolverProcessor {
boolean isAccessible = isAccessible(method);
final GroovyPsiElement resolveContext = state.get(RESOLVE_CONTEXT);
boolean isStaticsOK = isStaticsOK(method, resolveContext, true);
addCandidate(new GroovyResolveResultImpl(method, resolveContext, substitutor, isAccessible, isStaticsOK, true));
return !isAccessible || !isStaticsOK;
final GroovyResolveResultImpl candidate =
new GroovyResolveResultImpl(method, resolveContext, substitutor, isAccessible, isStaticsOK, true);
if (isAccessible && isStaticsOK) {
addCandidate(candidate);
return method instanceof GrGdkMethod; //don't stop searching if we found only gdk method
}
else {
myInapplicableCandidates.add(candidate);
return true;
}
}
@NotNull
@Override
public GroovyResolveResult[] getCandidates() {
final boolean hasApplicableCandidates = hasApplicableCandidates();
final GroovyResolveResult[] candidates = super.getCandidates();
if (hasApplicableCandidates) {
if (candidates.length <= 1) return candidates;
return new GroovyResolveResult[]{candidates[0]};
}
else {
return candidates;
}
}
}
@@ -48,7 +48,7 @@ public class MethodResolverProcessor extends ResolverProcessor {
private final PsiType[] myArgumentTypes;
private final boolean myAllVariants;
private final Set<GroovyResolveResult> myInapplicableCandidates = new LinkedHashSet<GroovyResolveResult>();
protected final Set<GroovyResolveResult> myInapplicableCandidates = new LinkedHashSet<GroovyResolveResult>();
private final boolean myIsConstructor;
private boolean myStopExecuting = false;
@@ -221,43 +221,51 @@ public class FindUsagesTest extends LightGroovyTestCase {
}
void testCapitalizedProperty1() {
myFixture.configureByText('_.groovy', '''\
doTest(1, '''\
class A {
def Pro<caret>p
}
new A().Prop''')
assertUsageCount(1);
}
void testCapitalizedProperty2() {
myFixture.configureByText('_.groovy', '''\
doTest(1, '''\
class A {
def Pro<caret>p
}
new A().prop''')
assertUsageCount(1)
}
void testCapitalizedProperty3() {
myFixture.configureByText('_.groovy', '''\
doTest(0, '''\
class A {
def pro<caret>p
}
new A().Prop''')
assertUsageCount(0)
}
void testCapitalizedProperty4() {
myFixture.configureByText('_.groovy', '''\
doTest(1, '''\
class A {
def p<caret>rop
}
new A().prop''')
assertUsageCount(1)
}
void testCategoryProperty() {
doTest(1, '''\
class Cat {
static def ge<caret>tFoo(Number s) {'num'}
}
use(Cat) {
2.foo
}
''')
}
private void doSuperMethodTest(String... firstParameterTypes) {
@@ -279,4 +287,9 @@ new A().prop''')
}
}
private void doTest(int usageCount, String text) {
myFixture.configureByText('_.groovy', text)
assertUsageCount(usageCount);
}
}
@@ -28,6 +28,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil
@@ -593,7 +594,7 @@ set<caret>Foo(2)
}
public void testUpperCaseFieldWithoutGetter() {
assertTrue resolve("A.groovy") instanceof GrAccessorMethod
assertInstanceOf(resolve("A.groovy"), GrAccessorMethod)
}
public void testGetterWithUpperCaseFieldReference() {
@@ -788,4 +789,15 @@ class A {
new A().pro<caret>p''')
assertNotNull ref.resolve()
}
void testGetChars() {
def ref = configureByText('''\
'abc'.cha<caret>rs
''')
def resolved = ref.resolve()
assertInstanceOf(resolved, GrGdkMethod)
def method = resolved.staticMethod as PsiMethod
assertEquals(method.parameterList.parameters[0].type.canonicalText, CommonClassNames.JAVA_LANG_STRING)
}
}
@@ -443,6 +443,7 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel {
}
final List<Change> changesForPatch = CommittedChangesTreeBrowser.collectChanges(lst, true);
for (Change change : changesForPatch) {
if (! isUnderOldDir(change, oldFilePath)) continue;
ContentRevision before = null;
ContentRevision after = null;
if (change.getBeforeRevision() != null) {
@@ -480,6 +481,22 @@ public class TreeConflictRefreshablePanel extends AbstractRefreshablePanel {
};
}
private boolean isUnderOldDir(Change change, FilePath path) {
if (change.getBeforeRevision() != null) {
final boolean isUnder = FileUtil.isAncestor(path.getIOFile(), change.getBeforeRevision().getFile().getIOFile(), true);
if (isUnder) {
return true;
}
}
if (change.getAfterRevision() != null) {
final boolean isUnder = FileUtil.isAncestor(path.getIOFile(), change.getAfterRevision().getFile().getIOFile(), true);
if (isUnder) {
return isUnder;
}
}
return false;
}
private FilePath rebasePath(final FilePath oldBase, final FilePath newBase, final FilePath path) {
final String relativePath = FileUtil.getRelativePath(oldBase.getPath(), path.getPath(), File.separatorChar);
//if (StringUtil.isEmptyOrSpaces(relativePath)) return path;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 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.
@@ -20,11 +20,9 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiReference;
import com.intellij.psi.XmlElementVisitor;
import com.intellij.psi.impl.source.PsiElementArrayConstructor;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.XmlChildRole;
import com.intellij.psi.xml.XmlElementContentGroup;
import com.intellij.psi.xml.XmlElementContentSpec;
@@ -35,17 +33,8 @@ import org.jetbrains.annotations.NotNull;
* @author Mike
*/
public class XmlElementContentSpecImpl extends XmlElementImpl implements XmlElementContentSpec, XmlElementType {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlElementContentSpecImpl");
private static final TokenSet GROUPS_FILTER = TokenSet.create(XML_ELEMENT_CONTENT_GROUP);
private static final PsiElementArrayConstructor<XmlElementContentGroup> GROUPS_CONSTRUCTOR = new PsiElementArrayConstructor<XmlElementContentGroup>() {
@Override
public XmlElementContentGroup[] newPsiElementArray(int length) {
return new XmlElementContentGroup[length];
}
};
public XmlElementContentSpecImpl() {
super(XML_ELEMENT_CONTENT_SPEC);
}