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

This commit is contained in:
Michael Golubev
2012-08-01 11:41:50 +02:00
68 changed files with 3193 additions and 2065 deletions
@@ -78,7 +78,10 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
if (myChild2 != null && StdTokenSets.COMMENT_BIT_SET.contains(myChild2.getElementType())) {
if (mySettings.KEEP_FIRST_COLUMN_COMMENT) {
if (myChild2.getElementType() == JavaTokenType.C_STYLE_COMMENT) {
myResult = Spacing.getReadOnlySpacing();
}
else if (mySettings.KEEP_FIRST_COLUMN_COMMENT) {
myResult = Spacing
.createKeepingFirstColumnSpacing(0, Integer.MAX_VALUE, true, mySettings.KEEP_BLANK_LINES_IN_CODE);
}
@@ -31,7 +31,7 @@ public interface PsiAnnotationMemberValue extends PsiElement {
ArrayFactory<PsiAnnotationMemberValue> ARRAY_FACTORY = new ArrayFactory<PsiAnnotationMemberValue>() {
@Override
public PsiAnnotationMemberValue[] create(final int count) {
return count == 0 ? PsiAnnotationMemberValue.EMPTY_ARRAY : new PsiAnnotationMemberValue[count];
return count == 0 ? EMPTY_ARRAY : new PsiAnnotationMemberValue[count];
}
};
}
@@ -36,7 +36,7 @@ public interface PsiNameValuePair extends PsiElement {
ArrayFactory<PsiNameValuePair> ARRAY_FACTORY = new ArrayFactory<PsiNameValuePair>() {
@Override
public PsiNameValuePair[] create(final int count) {
return count == 0 ? PsiNameValuePair.EMPTY_ARRAY : new PsiNameValuePair[count];
return count == 0 ? EMPTY_ARRAY : new PsiNameValuePair[count];
}
};
@@ -56,6 +56,9 @@ public interface PsiNameValuePair extends PsiElement {
@Nullable @NonNls
String getName();
@Nullable
String getLiteralValue();
/**
* Returns the value for the element.
*
@@ -89,6 +89,11 @@ public class ClsNameValuePairImpl extends ClsElementImpl implements PsiNameValue
return myNameIdentifier.getText();
}
@Override
public String getLiteralValue() {
return null;
}
@Override
public PsiAnnotationMemberValue getValue() {
return myMemberValue;
@@ -87,4 +87,14 @@ public class ClsStubPsiFactory extends StubPsiFactory {
public PsiTypeParameterList createTypeParameterList(PsiTypeParameterListStub stub) {
return new ClsTypeParametersListImpl(stub);
}
@Override
public PsiAnnotationParameterList createAnnotationParameterList(PsiAnnotationParameterListStub stub) {
return null; // todo
}
@Override
public PsiNameValuePair createNameValuePair(PsiNameValuePairStub stub) {
return null; // todo
}
}
@@ -0,0 +1,76 @@
/*
* 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.
* 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.java.stubs;
import com.intellij.lang.ASTNode;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
import com.intellij.psi.PsiAnnotationParameterList;
import com.intellij.psi.impl.java.stubs.impl.PsiAnnotationParameterListStubImpl;
import com.intellij.psi.impl.source.tree.java.AnnotationParamListElement;
import com.intellij.psi.impl.source.tree.java.PsiAnnotationParamListImpl;
import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
/**
* @author Dmitry Avdeev
* Date: 7/27/12
*/
public class JavaAnnotationParameterListType extends JavaStubElementType<PsiAnnotationParameterListStub, PsiAnnotationParameterList> {
protected JavaAnnotationParameterListType() {
super("ANNOTATION_PARAMETER_LIST", true);
}
@Override
public PsiAnnotationParameterList createPsi(@NotNull ASTNode node) {
return new PsiAnnotationParamListImpl(node);
}
@NotNull
@Override
public ASTNode createCompositeNode() {
return new AnnotationParamListElement();
}
@Override
public PsiAnnotationParameterListStub createStub(LighterAST tree, LighterASTNode node, StubElement parentStub) {
return new PsiAnnotationParameterListStubImpl(parentStub);
}
@Override
public PsiAnnotationParameterList createPsi(@NotNull PsiAnnotationParameterListStub stub) {
return getPsiFactory(stub).createAnnotationParameterList(stub);
}
@Override
public void serialize(PsiAnnotationParameterListStub stub, StubOutputStream dataStream) throws IOException {
}
@Override
public PsiAnnotationParameterListStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
return new PsiAnnotationParameterListStubImpl(parentStub);
}
@Override
public void indexStub(PsiAnnotationParameterListStub stub, IndexSink sink) {
}
}
@@ -0,0 +1,97 @@
/*
* 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.
* 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.java.stubs;
import com.intellij.lang.ASTNode;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.impl.cache.RecordUtil;
import com.intellij.psi.impl.java.stubs.impl.PsiNameValuePairStubImpl;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.java.NameValuePairElement;
import com.intellij.psi.impl.source.tree.java.PsiNameValuePairImpl;
import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.List;
/**
* @author Dmitry Avdeev
* Date: 7/27/12
*/
public class JavaNameValuePairType extends JavaStubElementType<PsiNameValuePairStub, PsiNameValuePair> {
protected JavaNameValuePairType() {
super("NAME_VALUE_PAIR", true);
}
@Override
public PsiNameValuePair createPsi(@NotNull ASTNode node) {
return new PsiNameValuePairImpl(node);
}
@NotNull
@Override
public ASTNode createCompositeNode() {
return new NameValuePairElement();
}
@Override
public PsiNameValuePairStub createStub(LighterAST tree, LighterASTNode node, StubElement parentStub) {
String name = null;
String value = null;
List<LighterASTNode> children = tree.getChildren(node);
for (LighterASTNode child : children) {
if (child.getTokenType() == JavaTokenType.IDENTIFIER) {
name = RecordUtil.intern(tree.getCharTable(), child);
}
else if (child.getTokenType() == JavaElementType.LITERAL_EXPRESSION) {
value = RecordUtil.intern(tree.getCharTable(), tree.getChildren(child).get(0));
value = StringUtil.stripQuotesAroundValue(value);
}
}
return new PsiNameValuePairStubImpl(parentStub, StringRef.fromString(name), StringRef.fromString(value));
}
@Override
public PsiNameValuePair createPsi(@NotNull PsiNameValuePairStub stub) {
return getPsiFactory(stub).createNameValuePair(stub);
}
@Override
public void serialize(PsiNameValuePairStub stub, StubOutputStream dataStream) throws IOException {
dataStream.writeName(stub.getName());
dataStream.writeName(stub.getValue());
}
@Override
public PsiNameValuePairStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
StringRef name = dataStream.readName();
return new PsiNameValuePairStubImpl(parentStub, name, dataStream.readName());
}
@Override
public void indexStub(PsiNameValuePairStub stub, IndexSink sink) {
}
}
@@ -27,6 +27,8 @@ import org.jetbrains.annotations.NotNull;
public interface JavaStubElementTypes {
JavaModifierListElementType MODIFIER_LIST = new JavaModifierListElementType();
JavaAnnotationElementType ANNOTATION = new JavaAnnotationElementType();
JavaAnnotationParameterListType ANNOTATION_PARAMETER_LIST = new JavaAnnotationParameterListType();
JavaNameValuePairType NAME_VALUE_PAIR = new JavaNameValuePairType();
JavaParameterElementType PARAMETER = new JavaParameterElementType();
JavaParameterListElementType PARAMETER_LIST = new JavaParameterListElementType();
JavaTypeParameterElementType TYPE_PARAMETER = new JavaTypeParameterElementType();
@@ -0,0 +1,26 @@
/*
* 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.
* 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.java.stubs;
import com.intellij.psi.PsiAnnotationParameterList;
import com.intellij.psi.stubs.StubElement;
/**
* @author Dmitry Avdeev
* Date: 7/27/12
*/
public interface PsiAnnotationParameterListStub extends StubElement<PsiAnnotationParameterList> {
}
@@ -0,0 +1,32 @@
/*
* 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.
* 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.java.stubs;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.stubs.StubElement;
import org.jetbrains.annotations.Nullable;
/**
* @author Dmitry Avdeev
* Date: 7/27/12
*/
public interface PsiNameValuePairStub extends StubElement<PsiNameValuePair> {
String getName();
@Nullable
String getValue();
}
@@ -21,10 +21,7 @@ package com.intellij.psi.impl.java.stubs;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.*;
import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
import com.intellij.psi.impl.source.tree.java.PsiTypeParameterExtendsBoundsListImpl;
import com.intellij.psi.impl.source.tree.java.PsiTypeParameterImpl;
import com.intellij.psi.impl.source.tree.java.PsiTypeParameterListImpl;
import com.intellij.psi.impl.source.tree.java.*;
public class SourceStubPsiFactory extends StubPsiFactory {
@Override
@@ -106,4 +103,14 @@ public class SourceStubPsiFactory extends StubPsiFactory {
public PsiTypeParameterList createTypeParameterList(PsiTypeParameterListStub stub) {
return new PsiTypeParameterListImpl(stub);
}
@Override
public PsiAnnotationParameterList createAnnotationParameterList(PsiAnnotationParameterListStub stub) {
return new PsiAnnotationParamListImpl(stub);
}
@Override
public PsiNameValuePair createNameValuePair(PsiNameValuePairStub stub) {
return new PsiNameValuePairImpl(stub);
}
}
@@ -47,4 +47,8 @@ public abstract class StubPsiFactory {
public abstract PsiTypeParameter createTypeParameter(PsiTypeParameterStub stub);
public abstract PsiTypeParameterList createTypeParameterList(PsiTypeParameterListStub stub);
public abstract PsiAnnotationParameterList createAnnotationParameterList(PsiAnnotationParameterListStub stub);
public abstract PsiNameValuePair createNameValuePair(PsiNameValuePairStub stub);
}
@@ -0,0 +1,33 @@
/*
* 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.
* 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.java.stubs.impl;
import com.intellij.psi.PsiAnnotationParameterList;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiAnnotationParameterListStub;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
/**
* @author Dmitry Avdeev
* Date: 7/27/12
*/
public class PsiAnnotationParameterListStubImpl extends StubBase<PsiAnnotationParameterList> implements PsiAnnotationParameterListStub {
public PsiAnnotationParameterListStubImpl(StubElement parent) {
super(parent, JavaStubElementTypes.ANNOTATION_PARAMETER_LIST);
}
}
@@ -20,6 +20,7 @@
package com.intellij.psi.impl.java.stubs.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
@@ -29,6 +30,10 @@ import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PatchedSoftReference;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class PsiAnnotationStubImpl extends StubBase<PsiAnnotation> implements PsiAnnotationStub {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.java.stubs.impl.PsiAnnotationStubImpl");
@@ -37,8 +42,18 @@ public class PsiAnnotationStubImpl extends StubBase<PsiAnnotation> implements Ps
private PatchedSoftReference<CompositeElement> myParsedFromRepository;
public PsiAnnotationStubImpl(final StubElement parent, final String text) {
this(parent, text, null);
}
public PsiAnnotationStubImpl(final StubElement parent, final String text, @Nullable List<Pair<String, String>> attributes) {
super(parent, JavaStubElementTypes.ANNOTATION);
myText = text;
if (attributes != null) {
PsiAnnotationParameterListStubImpl list = new PsiAnnotationParameterListStubImpl(this);
for (Pair<String, String> attribute : attributes) {
new PsiNameValuePairStubImpl(list, StringRef.fromString(attribute.first), StringRef.fromString(attribute.second));
}
}
}
@Override
@@ -0,0 +1,50 @@
/*
* 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.
* 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.java.stubs.impl;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiNameValuePairStub;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.Nullable;
/**
* @author Dmitry Avdeev
* Date: 7/27/12
*/
public class PsiNameValuePairStubImpl extends StubBase<PsiNameValuePair> implements PsiNameValuePairStub {
@Nullable private final StringRef myName;
@Nullable private final StringRef myValue;
public PsiNameValuePairStubImpl(StubElement parent, @Nullable StringRef name, @Nullable StringRef value) {
super(parent, JavaStubElementTypes.NAME_VALUE_PAIR);
myName = name;
myValue = value;
}
@Override
public String getName() {
return myName == null ? "value" : myName.getString();
}
@Override
public String getValue() {
return myValue == null ? null : myValue.getString();
}
}
@@ -37,7 +37,7 @@ import java.io.IOException;
* @author max
*/
public class JavaFileElementType extends ILightStubFileElementType<PsiJavaFileStub> {
public static final int STUB_VERSION = 10;
public static final int STUB_VERSION = 12;
public JavaFileElementType() {
super("java.FILE", JavaLanguage.INSTANCE);
@@ -66,6 +66,8 @@ public interface JavaElementType {
IElementType IMPORT_STATIC_STATEMENT = JavaStubElementTypes.IMPORT_STATIC_STATEMENT;
IElementType MODIFIER_LIST = JavaStubElementTypes.MODIFIER_LIST;
IElementType ANNOTATION = JavaStubElementTypes.ANNOTATION;
IElementType NAME_VALUE_PAIR = JavaStubElementTypes.NAME_VALUE_PAIR;
IElementType ANNOTATION_PARAMETER_LIST = JavaStubElementTypes.ANNOTATION_PARAMETER_LIST;
IElementType EXTENDS_LIST = JavaStubElementTypes.EXTENDS_LIST;
IElementType IMPLEMENTS_LIST = JavaStubElementTypes.IMPLEMENTS_LIST;
IElementType FIELD = JavaStubElementTypes.FIELD;
@@ -77,6 +79,7 @@ public interface JavaElementType {
IElementType PARAMETER_LIST = JavaStubElementTypes.PARAMETER_LIST;
IElementType EXTENDS_BOUND_LIST = JavaStubElementTypes.EXTENDS_BOUND_LIST;
IElementType THROWS_LIST = JavaStubElementTypes.THROWS_LIST;
IElementType LITERAL_EXPRESSION = new JavaCompositeElementType("LITERAL_EXPRESSION", PsiLiteralExpressionImpl.class);
IElementType IMPORT_STATIC_REFERENCE = new JavaCompositeElementType("IMPORT_STATIC_REFERENCE", PsiImportStaticReferenceElementImpl.class);
IElementType TYPE = new JavaCompositeElementType("TYPE", PsiTypeElementImpl.class);
@@ -86,7 +89,6 @@ public interface JavaElementType {
IElementType PACKAGE_STATEMENT = new JavaCompositeElementType("PACKAGE_STATEMENT", PsiPackageStatementImpl.class);
IElementType LOCAL_VARIABLE = new JavaCompositeElementType("LOCAL_VARIABLE", PsiLocalVariableImpl.class);
IElementType REFERENCE_EXPRESSION = new JavaCompositeElementType("REFERENCE_EXPRESSION", PsiReferenceExpressionImpl.class);
IElementType LITERAL_EXPRESSION = new JavaCompositeElementType("LITERAL_EXPRESSION", PsiLiteralExpressionImpl.class);
IElementType THIS_EXPRESSION = new JavaCompositeElementType("THIS_EXPRESSION", PsiThisExpressionImpl.class);
IElementType SUPER_EXPRESSION = new JavaCompositeElementType("SUPER_EXPRESSION", PsiSuperExpressionImpl.class);
IElementType PARENTH_EXPRESSION = new JavaCompositeElementType("PARENTH_EXPRESSION", PsiParenthesizedExpressionImpl.class);
@@ -131,8 +133,6 @@ public interface JavaElementType {
IElementType LABELED_STATEMENT = new JavaCompositeElementType("LABELED_STATEMENT", PsiLabeledStatementImpl.class);
IElementType ASSERT_STATEMENT = new JavaCompositeElementType("ASSERT_STATEMENT", PsiAssertStatementImpl.class);
IElementType ANNOTATION_ARRAY_INITIALIZER = new JavaCompositeElementType("ANNOTATION_ARRAY_INITIALIZER", PsiArrayInitializerMemberValueImpl.class);
IElementType NAME_VALUE_PAIR = new JavaCompositeElementType("NAME_VALUE_PAIR", PsiNameValuePairImpl.class, true);
IElementType ANNOTATION_PARAMETER_LIST = new JavaCompositeElementType("ANNOTATION_PARAMETER_LIST", PsiAnnotationParameterListImpl.class, true);
IElementType METHOD_RECEIVER = new JavaCompositeElementType("METHOD_RECEIVER", PsiMethodReceiverImpl.class);
class ICodeBlockElementType extends IErrorCounterReparseableElementType implements ICompositeElementType, ILightLazyParseableElementType {
@@ -28,11 +28,11 @@ import org.jetbrains.annotations.NotNull;
/**
* @author ven
*/
public class PsiAnnotationParameterListImpl extends PsiCommaSeparatedListImpl implements PsiAnnotationParameterList {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiAnnotationParameterListImpl");
public class AnnotationParamListElement extends PsiCommaSeparatedListImpl implements PsiAnnotationParameterList {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.AnnotationParamListElement");
private volatile PsiNameValuePair[] myCachedMembers = null;
public PsiAnnotationParameterListImpl() {
public AnnotationParamListElement() {
super(ANNOTATION_PARAMETER_LIST, NAME_VALUE_PAIR_BIT_SET);
}
@@ -0,0 +1,87 @@
/*
* 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.
* 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.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.util.CharTable;
import org.jetbrains.annotations.NotNull;
/**
* @author ven
*/
//Retrieves method reference from this pair, do NOT reuse!!!
public class NameValuePairElement extends CompositeElement {
public NameValuePairElement() {
super(JavaElementType.NAME_VALUE_PAIR);
}
@Override
public int getChildRole(ASTNode child) {
if (ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) {
return ChildRole.ANNOTATION_VALUE;
}
if (child.getElementType() == JavaTokenType.IDENTIFIER) {
return ChildRole.NAME;
}
if (child.getElementType() == JavaTokenType.EQ) {
return ChildRole.OPERATION_SIGN;
}
return ChildRoleBase.NONE;
}
@Override
public ASTNode findChildByRole(int role) {
if (role == ChildRole.NAME) {
return findChildByType(JavaTokenType.IDENTIFIER);
}
if (role == ChildRole.ANNOTATION_VALUE) {
return findChildByType(ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET);
}
if (role == ChildRole.OPERATION_SIGN) {
return findChildByType(JavaTokenType.EQ);
}
return null;
}
@Override
public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
final TreeElement treeElement = super.addInternal(first, last, anchor, before);
if (first == last && first.getElementType() == JavaTokenType.IDENTIFIER) {
LeafElement eq = Factory.createSingleLeafElement(JavaTokenType.EQ, "=", 0, 1, treeCharTab, getManager());
super.addInternal(eq, eq, first, Boolean.FALSE);
}
return treeElement;
}
@Override
public void deleteChildInternal(@NotNull ASTNode child) {
super.deleteChildInternal(child);
if (child.getElementType() == JavaTokenType.IDENTIFIER) {
final ASTNode sign = findChildByRole(ChildRole.OPERATION_SIGN);
if (sign != null) {
super.deleteChildInternal(sign);
}
}
}
}
@@ -91,12 +91,7 @@ public class PsiAnnotationImpl extends JavaStubPsiElement<PsiAnnotationStub> imp
@Override
@NotNull
public PsiAnnotationParameterList getParameterList() {
final PsiAnnotationStub stub = getStub();
if (stub != null) {
return (PsiAnnotationParameterList)stub.getTreeElement().findChildByRoleAsPsiElement(ChildRole.PARAMETER_LIST);
}
return PsiTreeUtil.getRequiredChildOfType(this, PsiAnnotationParameterList.class);
return getRequiredStubOrPsiChild(JavaStubElementTypes.ANNOTATION_PARAMETER_LIST);
}
@Override
@@ -183,7 +178,6 @@ public class PsiAnnotationImpl extends JavaStubPsiElement<PsiAnnotationStub> imp
if (attributes.length == 0) {
return !strict;
}
PsiAnnotationMemberValue value = attributes[0].getValue();
LOG.assertTrue(elementTypeFields.length > 0);
PsiClass elementTypeClass =
@@ -194,11 +188,15 @@ public class PsiAnnotationImpl extends JavaStubPsiElement<PsiAnnotationStub> imp
//return !ArrayUtil.contains("TYPE_USE", elementTypeFields);
}
PsiAnnotationMemberValue value = null;
for (String fieldName : elementTypeFields) {
PsiField field = elementTypeClass.findFieldByName(fieldName, false);
if (field == null) {
continue;
}
if (value == null) {
value = attributes[0].getValue();
}
if (value instanceof PsiArrayInitializerMemberValue) {
PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue)value).getInitializers();
for (PsiAnnotationMemberValue initializer : initializers) {
@@ -0,0 +1,51 @@
/*
* 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.
* 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.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiAnnotationParameterList;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiAnnotationParameterListStub;
import com.intellij.psi.impl.source.JavaStubPsiElement;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
* Date: 7/27/12
*/
public class PsiAnnotationParamListImpl extends JavaStubPsiElement<PsiAnnotationParameterListStub> implements
PsiAnnotationParameterList {
public PsiAnnotationParamListImpl(@NotNull PsiAnnotationParameterListStub stub) {
super(stub, JavaStubElementTypes.ANNOTATION_PARAMETER_LIST);
}
public PsiAnnotationParamListImpl(@NotNull ASTNode node) {
super(node);
}
@NotNull
@Override
public PsiNameValuePair[] getAttributes() {
return getStubOrPsiChildren(JavaStubElementTypes.NAME_VALUE_PAIR, PsiNameValuePair.ARRAY_FACTORY);
}
@NonNls
public String toString(){
return "PsiAnnotationParameterList:" + getText();
}
}
@@ -33,13 +33,11 @@ import org.jetbrains.annotations.NotNull;
public abstract class PsiCommaSeparatedListImpl extends CompositePsiElement implements Constants {
private final TokenSet myTypesOfElements;
protected PsiCommaSeparatedListImpl(IElementType type, final TokenSet typeOfElements) {
super(type);
myTypesOfElements = typeOfElements;
}
@Override
public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
if (myTypesOfElements.contains(first.getElementType()) && myTypesOfElements.contains(last.getElementType())) {
@@ -68,7 +66,6 @@ public abstract class PsiCommaSeparatedListImpl extends CompositePsiElement impl
return super.addInternal(first, last, anchor, before);
}
@Override
public void deleteChildInternal(@NotNull ASTNode child) {
if (myTypesOfElements.contains(child.getElementType())) {
@@ -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,115 +20,76 @@ 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.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiNameValuePairStub;
import com.intellij.psi.impl.source.JavaStubPsiElement;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.impl.source.tree.ChildRole;
import com.intellij.psi.impl.source.tree.ElementType;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.CharTable;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author ven
* @author Dmitry Avdeev
* Date: 7/27/12
*/
public class PsiNameValuePairImpl extends JavaStubPsiElement<PsiNameValuePairStub> implements PsiNameValuePair {
//Retrieves method reference from this pair, do NOT reuse!!!
public class PsiNameValuePairImpl extends CompositePsiElement implements PsiNameValuePair {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiNameValuePairImpl");
private volatile String myCachedName = null;
private volatile PsiIdentifier myCachedNameIdentifier = null;
private volatile PsiAnnotationMemberValue myCachedValue = null;
private volatile boolean myNameCached = false;
@Override
public void clearCaches() {
myNameCached = false;
myCachedName = null;
myCachedNameIdentifier = null;
myCachedValue = null;
super.clearCaches();
public PsiNameValuePairImpl(@NotNull PsiNameValuePairStub stub) {
super(stub, JavaStubElementTypes.NAME_VALUE_PAIR);
}
public PsiNameValuePairImpl() {
super(JavaElementType.NAME_VALUE_PAIR);
public PsiNameValuePairImpl(@NotNull ASTNode node) {
super(node);
}
@NotNull
@Override
public PsiIdentifier getNameIdentifier() {
PsiIdentifier cachedNameIdentifier = myCachedNameIdentifier;
if (!myNameCached) {
myCachedNameIdentifier = cachedNameIdentifier = (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.NAME);
myCachedName = cachedNameIdentifier == null ? null : cachedNameIdentifier.getText();
myNameCached = true;
}
return cachedNameIdentifier;
public NameValuePairElement getNode() {
return (NameValuePairElement)super.getNode();
}
@Override
public String getName() {
String cachedName = myCachedName;
if (!myNameCached) {
PsiIdentifier identifier;
myCachedNameIdentifier = identifier = (PsiIdentifier)findChildByRoleAsPsiElement(ChildRole.NAME);
myCachedName = cachedName = identifier == null ? null : identifier.getText();
myNameCached = true;
PsiNameValuePairStub stub = getStub();
if (stub == null) {
PsiIdentifier nameIdentifier = getNameIdentifier();
return nameIdentifier == null ? null : nameIdentifier.getText();
}
return cachedName;
else {
return stub.getName();
}
}
@Override
public String getLiteralValue() {
PsiNameValuePairStub stub = getStub();
return stub == null ? null : stub.getValue();
}
@Override
public PsiIdentifier getNameIdentifier() {
ASTNode node = getNode().findChildByRole(ChildRole.NAME);
return node == null ? null : (PsiIdentifier)node.getPsi();
}
@Override
public PsiAnnotationMemberValue getValue() {
PsiAnnotationMemberValue cachedValue = myCachedValue;
if (cachedValue == null) {
myCachedValue = cachedValue = (PsiAnnotationMemberValue)findChildByRoleAsPsiElement(ChildRole.ANNOTATION_VALUE);
}
return cachedValue;
ASTNode node = getNode().findChildByRole(ChildRole.ANNOTATION_VALUE);
return node == null ? null : (PsiAnnotationMemberValue)node.getPsi();
}
@Override
@NotNull
@Override
public PsiAnnotationMemberValue setValue(@NotNull PsiAnnotationMemberValue newValue) {
getValue().replace(newValue);
return getValue();
}
@Override
public int getChildRole(ASTNode child) {
if (ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET.contains(child.getElementType())) {
return ChildRole.ANNOTATION_VALUE;
}
if (child.getElementType() == JavaTokenType.IDENTIFIER) {
return ChildRole.NAME;
}
if (child.getElementType() == JavaTokenType.EQ) {
return ChildRole.OPERATION_SIGN;
}
return ChildRoleBase.NONE;
}
@Override
public ASTNode findChildByRole(int role) {
if (role == ChildRole.NAME) {
return findChildByType(JavaTokenType.IDENTIFIER);
}
if (role == ChildRole.ANNOTATION_VALUE) {
return findChildByType(ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET);
}
if (role == ChildRole.OPERATION_SIGN) {
return findChildByType(JavaTokenType.EQ);
}
return null;
}
public String toString() {
return "PsiNameValuePair";
}
@Override
public PsiReference getReference() {
@@ -167,7 +128,8 @@ public class PsiNameValuePairImpl extends CompositePsiElement implements PsiName
if (refClass == null) return null;
String name = getName();
if (name == null) name = PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME;
MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, PsiType.EMPTY_ARRAY, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
MethodSignature signature = MethodSignatureUtil
.createMethodSignature(name, PsiType.EMPTY_ARRAY, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
return MethodSignatureUtil.findMethodBySignature(refClass, signature, false);
}
@@ -184,10 +146,10 @@ public class PsiNameValuePairImpl extends CompositePsiElement implements PsiName
if (nameIdentifier != null) {
PsiImplUtil.setName(nameIdentifier, newElementName);
}
else if (ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET.contains(getFirstChildNode().getElementType())) {
else if (ElementType.ANNOTATION_MEMBER_VALUE_BIT_SET.contains(getNode().getFirstChildNode().getElementType())) {
PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
nameIdentifier = factory.createIdentifier(newElementName);
addBefore(nameIdentifier, SourceTreeToPsiMap.treeElementToPsi(getFirstChildNode()));
addBefore(nameIdentifier, SourceTreeToPsiMap.treeElementToPsi(getNode().getFirstChildNode()));
}
return PsiNameValuePairImpl.this;
@@ -227,24 +189,10 @@ public class PsiNameValuePairImpl extends CompositePsiElement implements PsiName
}
@Override
public TreeElement addInternal(TreeElement first, ASTNode last, ASTNode anchor, Boolean before) {
final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
final TreeElement treeElement = super.addInternal(first, last, anchor, before);
if (first == last && first.getElementType() == JavaTokenType.IDENTIFIER) {
LeafElement eq = Factory.createSingleLeafElement(JavaTokenType.EQ, "=", 0, 1, treeCharTab, getManager());
super.addInternal(eq, eq, first, Boolean.FALSE);
}
return treeElement;
public String toString() {
return "PsiNameValuePair";
}
@Override
public void deleteChildInternal(@NotNull ASTNode child) {
super.deleteChildInternal(child);
if (child.getElementType() == JavaTokenType.IDENTIFIER) {
final ASTNode sign = findChildByRole(ChildRole.OPERATION_SIGN);
if (sign != null) {
super.deleteChildInternal(sign);
}
}
}
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiNameValuePairImpl");
}
@@ -92,6 +92,7 @@ public class JavaStubBuilderTest extends LightIdeaTestCase {
" CLASS:PsiClassStub[interface deprecatedA name=I fqn=p.I]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=5120]\n" +
" ANNOTATION:PsiAnnotationStub[@java.lang.Deprecated]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n" +
@@ -308,6 +309,7 @@ public class JavaStubBuilderTest extends LightIdeaTestCase {
" METHOD:PsiMethodStub[close:void]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
" ANNOTATION:PsiAnnotationStub[@Override]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
@@ -339,11 +341,45 @@ public class JavaStubBuilderTest extends LightIdeaTestCase {
" METHOD:PsiMethodStub[iterator:Iterator<String>]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=1]\n" +
" ANNOTATION:PsiAnnotationStub[@Override]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" PARAMETER_LIST:PsiParameterListStub\n" +
" THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n");
}
public void testAnnotationParameters() throws Exception {
doTest("@Deprecated(\"bar\")\n" +
"class Foo {\n" +
"}",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[deprecatedA name=Foo fqn=Foo]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" ANNOTATION:PsiAnnotationStub[@Deprecated(\"bar\")]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" NAME_VALUE_PAIR:PsiNameValuePairStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n");
}
public void testAnnotation() throws Exception {
doTest("@Deprecated\n" +
"class Foo {\n" +
"}",
"PsiJavaFileStub []\n" +
" IMPORT_LIST:PsiImportListStub\n" +
" CLASS:PsiClassStub[deprecatedA name=Foo fqn=Foo]\n" +
" MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" +
" ANNOTATION:PsiAnnotationStub[@Deprecated]\n" +
" ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" +
" TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" +
" EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" +
" IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n");
}
public void testSOEProof() {
final StringBuilder sb = new StringBuilder();
final SecureRandom random = new SecureRandom();
@@ -489,4 +489,18 @@ public class JavaFormatterIndentationTest extends AbstractJavaFormatterTest {
")"
);
}
public void testCStyleCommentIsNotMoved() throws Exception {
// IDEA-87087
doClassTest(
" /*\n" +
" this is a c-style comment\n" +
" */\n" +
" // This is a line comment",
" /*\n" +
" this is a c-style comment\n" +
" */\n" +
"// This is a line comment"
);
}
}
@@ -354,7 +354,7 @@ final class BuildSession implements Runnable, CanceledStatus {
LOG.info("Applying deleted path from fs event to artifacts: " + file.getPath());
}
for (ArtifactRootDescriptor rootDescriptor : descriptor)
pd.fsState.registerDeleted(rootDescriptor.getArtifactName(), rootDescriptor.getRootId().getArtifactId(), deleted,
pd.fsState.registerDeleted(rootDescriptor.getArtifactName(), rootDescriptor.getArtifactId(), deleted,
artifactTimestamps);
}
}
@@ -1,54 +0,0 @@
package org.jetbrains.jps.incremental.artifacts;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* @author nik
*/
public class ArtifactRootId {
private final int myArtifactId;
private final int myRootIndex;
public ArtifactRootId(int artifactId, int rootIndex) {
myArtifactId = artifactId;
myRootIndex = rootIndex;
}
public ArtifactRootId(DataInput input) throws IOException {
myArtifactId = input.readInt();
myRootIndex = input.readInt();
}
public int getArtifactId() {
return myArtifactId;
}
public int getRootIndex() {
return myRootIndex;
}
public void save(DataOutput out) throws IOException {
out.writeInt(myArtifactId);
out.writeInt(myRootIndex);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ArtifactRootId id = (ArtifactRootId)o;
return myArtifactId == id.myArtifactId && myRootIndex == id.myRootIndex;
}
@Override
public int hashCode() {
return 31 * myArtifactId + myRootIndex;
}
}
@@ -24,13 +24,11 @@ import java.util.*;
*/
public class ArtifactRootsIndex {
private MultiMap<File, ArtifactRootDescriptor> myRootToDescriptorMap;
private Map<ArtifactRootId, ArtifactRootDescriptor> myIdToDescriptorMap;
private Map<JpsArtifact, ArtifactInstructionsBuilder> myInstructions;
public ArtifactRootsIndex(JpsModel model, Project project, BuildDataManager manager, ModuleRootsIndex rootsIndex) {
myRootToDescriptorMap = new MultiMap<File, ArtifactRootDescriptor>();
myInstructions = new HashMap<JpsArtifact, ArtifactInstructionsBuilder>();
myIdToDescriptorMap = new HashMap<ArtifactRootId, ArtifactRootDescriptor>();
ArtifactsBuildData data = manager.getArtifactsBuildData();
for (JpsArtifact artifact : JpsArtifactService.getInstance().getArtifacts(model.getProject())) {
int artifactId = data.getArtifactId(artifact);
@@ -44,7 +42,6 @@ public class ArtifactRootsIndex {
for (Pair<ArtifactRootDescriptor, DestinationInfo> pair : builder.getInstructions()) {
ArtifactRootDescriptor descriptor = pair.getFirst();
myRootToDescriptorMap.putValue(descriptor.getRootFile(), descriptor);
myIdToDescriptorMap.put(descriptor.getRootId(), descriptor);
}
}
}
@@ -3,7 +3,6 @@ package org.jetbrains.jps.incremental.artifacts.instructions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.incremental.CompileContext;
import org.jetbrains.jps.incremental.artifacts.ArtifactOutputToSourceMapping;
import org.jetbrains.jps.incremental.artifacts.ArtifactRootId;
import org.jetbrains.jps.incremental.artifacts.ArtifactSourceToOutputMapping;
import java.io.File;
@@ -15,22 +14,24 @@ import java.io.IOException;
public abstract class ArtifactRootDescriptor {
protected final File myRoot;
private final SourceFileFilter myFilter;
private final ArtifactRootId myRootId;
private final int myRootIndex;
private final int myArtifactId;
private final String myArtifactName;
protected ArtifactRootDescriptor(File root, @NotNull SourceFileFilter filter, int index, int artifactId, String artifactName) {
myRoot = root;
myFilter = filter;
myRootIndex = index;
myArtifactId = artifactId;
myArtifactName = artifactName;
myRootId = new ArtifactRootId(artifactId, index);
}
public final String getArtifactName() {
return myArtifactName;
}
public final ArtifactRootId getRootId() {
return myRootId;
public int getArtifactId() {
return myArtifactId;
}
@NotNull
@@ -48,6 +49,6 @@ public abstract class ArtifactRootDescriptor {
}
public int getRootIndex() {
return myRootId.getRootIndex();
return myRootIndex;
}
}
@@ -200,7 +200,7 @@ public class BuildFSState extends FSState {
}
else {
marked = true;
storage.update(descriptor.getRootId().getArtifactId(), path, stamp);
storage.update(descriptor.getArtifactId(), path, stamp);
}
}
}
@@ -117,7 +117,7 @@ public class FSState {
public void markDirty(ArtifactRootDescriptor descriptor, String filePath, ArtifactSourceTimestampStorage timestamps) throws IOException {
markRecompile(descriptor, filePath);
timestamps.removeTimestamp(filePath, descriptor.getRootId().getArtifactId());
timestamps.removeTimestamp(filePath, descriptor.getArtifactId());
}
public void markRecompile(ArtifactRootDescriptor descriptor, String filePath) {
@@ -226,4 +226,9 @@ public abstract class StubBase<T extends PsiElement> extends UserDataHolderBase
((StubBase)child).printTree(builder, nestingLevel + 1);
}
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
@@ -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.
@@ -187,7 +187,8 @@ public interface CodeStyleSettingsCustomizable {
CATCH_ON_NEW_LINE,
FINALLY_ON_NEW_LINE,
INDENT_CASE_FROM_SWITCH,
SPECIAL_ELSE_IF_TREATMENT
SPECIAL_ELSE_IF_TREATMENT,
ENUM_CONSTANTS_WRAP
}
@@ -174,7 +174,9 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
}
public void setAllowContentUpdateFromContext(boolean allow) {
restartAutoUpdate(allow);
if (hasActiveDockedDocWindow()) {
restartAutoUpdate(allow);
}
}
public void showJavaDocInfoAtToolWindow(@NotNull PsiElement element, @NotNull PsiElement original) {
@@ -70,10 +70,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.Alarm;
import com.intellij.util.Consumer;
import com.intellij.util.EditorPopupHandler;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.*;
import com.intellij.util.text.CharArrayUtil;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NonNls;
@@ -92,9 +89,9 @@ import java.util.concurrent.CopyOnWriteArraySet;
public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableConsoleView, DataProvider, OccurenceNavigator {
@NonNls private static final String CONSOLE_VIEW_POPUP_MENU = "ConsoleView.PopupMenu";
private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.ConsoleViewImpl");
private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.ConsoleViewImpl");
private static final int FLUSH_DELAY = 200; //TODO : make it an option
private static final int DEFAULT_FLUSH_DELAY = SystemProperties.getIntProperty("console.flush.delay.ms", 200);
public static final Key<ConsoleViewImpl> CONSOLE_VIEW_IN_EDITOR_VIEW = Key.create("CONSOLE_VIEW_IN_EDITOR_VIEW");
@@ -108,7 +105,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
private final CommandLineFolding myCommandLineFolding = new CommandLineFolding();
private final DisposedPsiManagerCheck myPsiDisposedCheck;
private final boolean isViewer;
private final boolean isViewer;
private ConsoleState myState;
@@ -117,17 +114,18 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
private final Alarm mySpareTimeAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this);
@Nullable
private final Alarm myHeavyAlarm;
private int myHeavyUpdateTicket;
private int myHeavyUpdateTicket;
private final CopyOnWriteArraySet<ChangeListener> myListeners = new CopyOnWriteArraySet<ChangeListener>();
private final ArrayList<AnAction> customActions = new ArrayList<AnAction>();
private final ConsoleBuffer myBuffer = new ConsoleBuffer();
private boolean myUpdateFoldingsEnabled = true;
private EditorHyperlinkSupport myHyperlinks;
private MyDiffContainer myJLayeredPane;
private JPanel myMainPanel;
private final Runnable myFinishProgress;
private final CopyOnWriteArraySet<ChangeListener> myListeners = new CopyOnWriteArraySet<ChangeListener>();
private final ArrayList<AnAction> customActions = new ArrayList<AnAction>();
private final ConsoleBuffer myBuffer = new ConsoleBuffer();
private boolean myUpdateFoldingsEnabled = true;
private EditorHyperlinkSupport myHyperlinks;
private MyDiffContainer myJLayeredPane;
private JPanel myMainPanel;
private final Runnable myFinishProgress;
private boolean myAllowHeavyFilters = false;
private int myFlushDelay = DEFAULT_FLUSH_DELAY;
public Editor getEditor() {
return myEditor;
@@ -535,11 +533,20 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
}
if (myEditor != null && !myFlushAlarm.isDisposed()) {
final boolean shouldFlushNow = myBuffer.isUseCyclicBuffer() && myBuffer.getLength() >= myBuffer.getCyclicBufferSize();
addFlushRequest(new MyFlushRunnable(), shouldFlushNow ? 0 : FLUSH_DELAY);
addFlushRequest(new MyFlushRunnable(), shouldFlushNow ? 0 : myFlushDelay);
}
}
}
public void setFlushDelay(int flushDelay) throws IllegalArgumentException {
if (flushDelay < 0) {
throw new IllegalArgumentException("Can't accept negative flush delay value: " + flushDelay);
}
synchronized (LOCK) { // Ensure 'happens-before' condition with the variable read.
myFlushDelay = flushDelay;
}
}
protected void beforeExternalAddContentToDocument(int length, ConsoleViewContentType contentType) {
synchronized (LOCK) {
myContentSize += length;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,47 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.actions;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.ToggleAction;
import javax.swing.*;
/**
* @author Konstantin Bulenkov
*/
public abstract class TabsPlacementAction extends ToggleAction {
abstract int getPlace();
@Override
public boolean isSelected(AnActionEvent e) {
return UISettings.getInstance().EDITOR_TAB_PLACEMENT == getPlace();
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
UISettings.getInstance().EDITOR_TAB_PLACEMENT = getPlace();
LafManager.getInstance().repaintUI();
UISettings.getInstance().fireUISettingsChanged();
}
public static class Top extends TabsPlacementAction {int getPlace() {return SwingConstants.TOP;}}
public static class Left extends TabsPlacementAction {int getPlace() {return SwingConstants.LEFT;}}
public static class Bottom extends TabsPlacementAction {int getPlace() {return SwingConstants.BOTTOM;}}
public static class Right extends TabsPlacementAction {int getPlace() {return SwingConstants.RIGHT;}}
}
@@ -485,10 +485,30 @@ public class AbstractPopup implements JBPopup {
show(relativePointWithDominantRectangle(layeredPane, dominantArea));
}
else {
show(JBPopupFactory.getInstance().guessBestPopupLocation(editor));
show(guessBestPopupLocation(editor));
}
}
@NotNull
private RelativePoint guessBestPopupLocation(@NotNull Editor editor) {
RelativePoint preferredLocation = JBPopupFactory.getInstance().guessBestPopupLocation(editor);
if (myDimensionServiceKey == null) {
return preferredLocation;
}
Dimension preferredSize = DimensionService.getInstance().getSize(myDimensionServiceKey, myProject);
if (preferredSize == null) {
return preferredLocation;
}
Rectangle preferredBounds = new Rectangle(preferredLocation.getScreenPoint(), preferredSize);
Rectangle adjustedBounds = new Rectangle(preferredBounds);
ScreenUtil.moveRectangleToFitTheScreen(adjustedBounds);
if (preferredBounds.y - adjustedBounds.y <= 0) {
return preferredLocation;
}
int adjustedY = preferredBounds.y - (editor.getLineHeight() * 3 / 2) - preferredSize.height;
return adjustedY >= 0 ? RelativePoint.fromScreen(new Point(preferredBounds.x, adjustedY)) : preferredLocation;
}
public void addPopupListener(JBPopupListener listener) {
myListeners.add(listener);
}
@@ -340,6 +340,12 @@
<action id="UnsplitAll" class="com.intellij.ide.actions.UnsplitAllAction"/>
<action id="NextSplitter" class="com.intellij.ide.actions.NextSplitAction"/>
<action id="PrevSplitter" class="com.intellij.ide.actions.PrevSplitAction"/>
<group id="TabsPlacementGroup" popup="true" text="Tabs Placement">
<action id="TabsPlacementTop" text="Top" class="com.intellij.ide.actions.TabsPlacementAction$Top" />
<action id="TabsPlacementBottom" text="Bottom" class="com.intellij.ide.actions.TabsPlacementAction$Bottom" />
<action id="TabsPlacementLeft" text="Left" class="com.intellij.ide.actions.TabsPlacementAction$Left" />
<action id="TabsPlacementRight" text="Right" class="com.intellij.ide.actions.TabsPlacementAction$Right" />
</group>
</group>
<group id="BackgroundTasks" popup="true">
@@ -429,6 +435,7 @@
<action id="MoveEditorToOppositeTabGroup" class="com.intellij.openapi.fileEditor.impl.MoveEditorToOppositeTabGroupAction"/>
<reference ref="ChangeSplitOrientation"/>
<reference ref="PinActiveTab"/>
<reference ref="TabsPlacementGroup"/>
<separator/>
<reference ref="NextTab"/>
<reference ref="PreviousTab"/>
@@ -362,7 +362,7 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
void renameElement(PsiElement element, String newName);
void allowTreeAccessForFile(@NotNull VirtualFile file);
void allowTreeAccessForFile(VirtualFile file);
void allowTreeAccessForAllFiles();
@@ -236,6 +236,8 @@ public class ExtensionDomExtender extends DomExtender<Extensions> {
private static String getStringAttribute(final PsiAnnotation annotation,
final String name,
final PsiConstantEvaluationHelper evalHelper) {
String value = getAttributeValue(annotation, name);
if (value != null) return value;
final Object o = evalHelper.computeConstantExpression(annotation.findAttributeValue(name), false);
return o instanceof String && StringUtil.isNotEmpty((String)o)? (String)o : null;
}
@@ -243,8 +245,20 @@ public class ExtensionDomExtender extends DomExtender<Extensions> {
private static boolean getBooleanAttribute(final PsiAnnotation annotation,
final String name,
final PsiConstantEvaluationHelper evalHelper) {
String value = getAttributeValue(annotation, name);
if (value != null) return Boolean.parseBoolean(value);
final Object o = evalHelper.computeConstantExpression(annotation.findAttributeValue(name), false);
return o instanceof Boolean? ((Boolean)o).booleanValue() : false;
return o instanceof Boolean && ((Boolean)o).booleanValue();
}
@Nullable
private static String getAttributeValue(PsiAnnotation annotation, String name) {
for (PsiNameValuePair attribute : annotation.getParameterList().getAttributes()) {
if (name.equals(attribute.getName())) {
return attribute.getLiteralValue();
}
}
return null;
}
@Nullable
@@ -0,0 +1,11 @@
int f(Color a) {
<spot>switch(a)
{
case Blue:
break;
case Green:
break;
case Red:
break;
}</spot>
}
@@ -0,0 +1,4 @@
int f(Color a) {
<spot>switch(a) {
}</spot>
}
@@ -0,0 +1,5 @@
<html>
<body>
This intention will fill in any missing case labels on a switch statement with an enumerated type as it's switch expression
</body>
</html>
+9 -1
View File
@@ -732,7 +732,7 @@
groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
implementationClass="org.jetbrains.plugins.groovy.codeInspection.confusing.GroovyNegatedConditionalInspection"/>
<localInspection language="Groovy" groupPath="Groovy" shortName="GroovyInArgumentCheck" displayName="Incompatible 'in' argument types"
enabledByDefault="false" groupName="Probable bugs" level="WARNING"
enabledByDefault="true" groupName="Probable bugs" level="WARNING"
implementationClass="org.jetbrains.plugins.groovy.codeInspection.bugs.GroovyInArgumentCheckInspection"/>
<localInspection language="Groovy" groupPath="Groovy" shortName="GroovyNegatedIf" displayName="Negated if condition expression"
groupName="Potentially confusing code constructs" enabledByDefault="false" level="WARNING"
@@ -1012,6 +1012,7 @@
</intentionAction>
-->
<!-- comments -->
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
@@ -1204,6 +1205,13 @@
<className>org.jetbrains.plugins.groovy.intentions.declaration.GrCreateFieldForParameterIntention</className>
</intentionAction>
<!--other-->
<intentionAction>
<bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
<categoryKey>intention.category.groovy/intention.category.groovy.other</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.other.GrCreateMissingSwitchBranchesIntention</className>
</intentionAction>
<projectService serviceInterface="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWindowWrapper"
serviceImplementation="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWindowWrapper"/>
@@ -317,3 +317,9 @@ create.inner.class=Create Inner Class {0}
annotation.field.can.only.be.used.within.a.script.body=Annotation @Field can only be used within a script body
annotation.field.can.only.be.used.within.a.script=Annotation @Field can only be used within a script
public.modifier.is.not.allowed.in.interfaces='public' modifier is not allowed in interfaces
return.type.is.incompatible=The return type of {0} in {1} is incompatible with {2} in {3}
anonymous.class.derived.from=anonymous class derived from
throws.clause.is.not.allowed.in.at.interface='throws' clause is not allowed in @interface members
at.interface.0.does.not.contain.attribute=@interface ''{0}'' does not contain attribute ''{1}''
duplicate.attribute=Duplicate attribute
missed.attributes=Missed attributes: {0}
@@ -41,11 +41,10 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.*;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
@@ -71,7 +70,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
@@ -90,9 +89,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.types.*;
@@ -100,6 +97,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.util.GrVariableDeclarationOwner
import org.jetbrains.plugins.groovy.lang.psi.impl.TypeInferenceHelper;
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrScriptField;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
@@ -130,6 +128,29 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
myHolder = null;
}
else {
final PsiElement parent = element.getParent();
if (parent instanceof GrMethod) {
if (element.equals(((GrMethod)parent).getNameIdentifierGroovy()) &&
((GrMethod)parent).getReturnTypeElementGroovy() == null) {
checkMethodReturnType((GrMethod)parent, element, holder);
}
}
else if (parent instanceof GrField) {
final GrField field = (GrField)parent;
if (element.equals(field.getNameIdentifierGroovy())) {
final GrAccessorMethod[] getters = field.getGetters();
for (GrAccessorMethod getter : getters) {
checkMethodReturnType(getter, field.getNameIdentifierGroovy(), holder);
}
final GrAccessorMethod setter = field.getSetter();
if (setter != null) {
checkMethodReturnType(setter, field.getNameIdentifierGroovy(), holder);
}
}
}
}
}
@Override
@@ -777,6 +798,91 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
}
@Override
public void visitTypeElement(GrTypeElement typeElement) {
super.visitTypeElement(typeElement);
final PsiElement parent = typeElement.getParent();
if (!(parent instanceof GrMethod)) return;
checkMethodReturnType(((GrMethod)parent), typeElement, myHolder);
}
private static void checkMethodReturnType(PsiMethod method, PsiElement toHighlight, AnnotationHolder holder) {
final HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
final List<HierarchicalMethodSignature> superSignatures = signature.getSuperSignatures();
PsiType returnType = signature.getSubstitutor().substitute(method.getReturnType());
for (HierarchicalMethodSignature superMethodSignature : superSignatures) {
PsiMethod superMethod = superMethodSignature.getMethod();
PsiType declaredReturnType = superMethod.getReturnType();
PsiType superReturnType = superMethodSignature.getSubstitutor().substitute(declaredReturnType);
if (superReturnType == PsiType.VOID && method instanceof GrMethod && ((GrMethod)method).getReturnTypeElementGroovy() == null) return;
if (superMethodSignature.isRaw()) superReturnType = TypeConversionUtil.erasure(declaredReturnType);
if (returnType == null || superReturnType == null || method == superMethod) continue;
PsiClass superClass = superMethod.getContainingClass();
if (superClass == null) continue;
String highlightInfo = checkSuperMethodSignature(superMethod, superMethodSignature, superReturnType, method, signature, returnType);
if (highlightInfo != null) {
holder.createErrorAnnotation(toHighlight, highlightInfo);
return;
}
}
}
@Nullable
private static String checkSuperMethodSignature(PsiMethod superMethod,
MethodSignatureBackedByPsiMethod superMethodSignature,
PsiType superReturnType,
PsiMethod method,
MethodSignatureBackedByPsiMethod methodSignature,
PsiType returnType) {
if (superReturnType == null) return null;
PsiType substitutedSuperReturnType;
if (!superMethodSignature.isRaw() && superMethodSignature.equals(methodSignature)) { //see 8.4.5
PsiSubstitutor unifyingSubstitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature,
superMethodSignature);
substitutedSuperReturnType = unifyingSubstitutor == null
? superReturnType
: unifyingSubstitutor.substitute(superMethodSignature.getSubstitutor().substitute(superReturnType));
}
else {
substitutedSuperReturnType = TypeConversionUtil.erasure(superReturnType);
}
if (returnType.equals(substitutedSuperReturnType)) return null;
if (!(returnType instanceof PsiPrimitiveType) &&
substitutedSuperReturnType.getDeepComponentType() instanceof PsiClassType &&
TypeConversionUtil.isAssignable(substitutedSuperReturnType, returnType)) {
return null;
}
String qName = getQName(method);
String baseQName = getQName(superMethod);
final String presentation = returnType.getCanonicalText()+" "+GroovyPresentationUtil.getSignaturePresentation(methodSignature);
final String basePresentation = superReturnType.getCanonicalText()+" "+GroovyPresentationUtil.getSignaturePresentation(superMethodSignature);
return GroovyBundle.message("return.type.is.incompatible", presentation, qName, basePresentation, baseQName);
}
@NotNull
private static String getQName(PsiMethod method) {
final PsiClass aClass = method.getContainingClass();
if (aClass instanceof PsiAnonymousClass) {
return GroovyBundle.message("anonymous.class.derived.from") + " " + ((PsiAnonymousClass)aClass).getBaseClassType().getCanonicalText();
}
if (aClass != null) {
final String qname = aClass.getQualifiedName();
if (qname != null) {
return qname;
}
}
return "<null>";
}
private void checkTypeArgForPrimitive(@Nullable GrTypeElement element, String message) {
if (element == null || !(element.getType() instanceof PsiPrimitiveType)) return;
@@ -1115,7 +1221,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
public void visitAnnotation(GrAnnotation annotation) {
super.visitAnnotation(annotation);
final GrCodeReferenceElement ref = annotation.getClassReference();
final PsiElement resolved = ref.resolve();
@@ -1140,6 +1245,131 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
}
}
@Override
public void visitAnnotationArgumentList(GrAnnotationArgumentList annotationArgumentList) {
final GrAnnotation annotation = (GrAnnotation)annotationArgumentList.getParent();
final PsiElement resolved = annotation.getClassReference().resolve();
if (resolved == null) return;
assert resolved instanceof PsiClass;
final PsiClass annot = (PsiClass)resolved;
final GrAnnotationNameValuePair[] attributes = annotationArgumentList.getAttributes();
Set<String> usedAttrs = new HashSet<String>();
if (attributes.length == 1 && attributes[0].getNameIdentifierGroovy() == null) {
checkAnnotationValue(annot, attributes[0], "value", usedAttrs, attributes[0].getValue());
}
else {
for (GrAnnotationNameValuePair attribute : attributes) {
final PsiElement identifier = attribute.getNameIdentifierGroovy();
final String name = identifier.getText();
checkAnnotationValue(annot, identifier, name, usedAttrs, attribute.getValue());
}
}
List<String> missedAttrs = new ArrayList<String>();
final PsiMethod[] methods = annot.getMethods();
for (PsiMethod method : methods) {
final String name = method.getName();
if (usedAttrs.contains(name) ||
method instanceof PsiAnnotationMethod && ((PsiAnnotationMethod)method).getDefaultValue() != null) {
continue;
}
missedAttrs.add(name);
}
if (!missedAttrs.isEmpty()) {
myHolder.createErrorAnnotation(annotation.getClassReference(), GroovyBundle.message("missed.attributes", StringUtil.join(missedAttrs, ", ")));
}
}
private void checkAnnotationValue(PsiClass annot,
PsiElement identifierToHighlight,
String name,
Set<String> usedAttrs,
GrAnnotationMemberValue value) {
if (usedAttrs.contains(name)) {
myHolder.createErrorAnnotation(identifierToHighlight, GroovyBundle.message("duplicate.attribute"));
}
usedAttrs.add(name);
final PsiMethod[] methods = annot.findMethodsByName(name, false);
if (methods.length == 0) {
myHolder.createErrorAnnotation(identifierToHighlight,
GroovyBundle.message("at.interface.0.does.not.contain.attribute", annot.getQualifiedName(), name));
}
else {
final PsiMethod method = methods[0];
final PsiType ltype = method.getReturnType();
if (ltype != null && value != null) {
checkAnnotationValueByType(value, ltype);
}
}
}
@Override
public void visitDefaultAnnotationValue(GrDefaultAnnotationValue defaultAnnotationValue) {
final GrAnnotationMemberValue value = defaultAnnotationValue.getDefaultValue();
final PsiElement parent = defaultAnnotationValue.getParent();
assert parent instanceof GrAnnotationMethod;
final PsiType type = ((GrAnnotationMethod)parent).getReturnType();
checkAnnotationValueByType(value, type);
}
private void checkAnnotationValueByType(GrAnnotationMemberValue value, PsiType ltype) {
final GlobalSearchScope resolveScope = value.getResolveScope();
final PsiManager manager = value.getManager();
if (value instanceof GrExpression) {
final PsiType rtype = ((GrExpression)value).getType();
if (rtype != null && !checkAnnoTypeAssignable(ltype, resolveScope, manager, rtype)) {
myHolder.createErrorAnnotation(value, GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText()));
}
}
else if (value instanceof GrAnnotation) {
final PsiElement resolved = ((GrAnnotation)value).getClassReference().resolve();
if (resolved instanceof PsiClass) {
final PsiClassType rtype = JavaPsiFacade.getElementFactory(value.getProject()).createType((PsiClass)resolved, PsiSubstitutor.EMPTY);
if (!checkAnnoTypeAssignable(ltype, resolveScope, manager, rtype)) {
myHolder.createErrorAnnotation(value, GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText()));
}
}
}
else if (value instanceof GrAnnotationArrayInitializer) {
if (ltype instanceof PsiArrayType) {
final PsiType componentType = ((PsiArrayType)ltype).getComponentType();
final GrAnnotationMemberValue[] initializers = ((GrAnnotationArrayInitializer)value).getInitializers();
for (GrAnnotationMemberValue initializer : initializers) {
checkAnnotationValueByType(initializer, componentType);
}
}
else {
final PsiType rtype = TypesUtil.getTupleByAnnotationArrayInitializer((GrAnnotationArrayInitializer)value);
if (!checkAnnoTypeAssignable(ltype, resolveScope, manager, rtype)) {
myHolder.createErrorAnnotation(value, GroovyBundle.message("cannot.assign", rtype.getPresentableText(), ltype.getPresentableText()));
}
}
}
}
private static boolean checkAnnoTypeAssignable(PsiType type, GlobalSearchScope resolveScope, PsiManager manager, PsiType rtype) {
rtype = TypesUtil.unboxPrimitiveTypeWrapper(rtype);
if (TypesUtil.isAssignableByMethodCallConversion(type, rtype, manager, resolveScope)) return true;
if (!(type instanceof PsiArrayType)) return false;
final PsiType componentType = ((PsiArrayType)type).getComponentType();
return TypesUtil.isAssignableByMethodCallConversion(componentType, rtype, manager, resolveScope);
}
@Override
public void visitImportStatement(GrImportStatement importStatement) {
checkAnnotationList(myHolder, importStatement.getAnnotationList(), GroovyBundle.message("import.statement.cannot.have.modifiers"));
@@ -70,7 +70,7 @@ public class GroovyInArgumentCheckInspection extends BaseInspection {
GrExpression leftOperand = expression.getLeftOperand();
GrExpression rightOperand = expression.getRightOperand();
if (leftOperand == null || rightOperand == null) return;
if (rightOperand == null) return;
PsiType ltype = leftOperand.getType();
PsiType rtype = rightOperand.getType();
@@ -114,4 +114,9 @@ public class GroovyInArgumentCheckInspection extends BaseInspection {
registerError(expression, ltype, rtype);
}
}
@Override
public boolean isEnabledByDefault() {
return true;
}
}
@@ -6,6 +6,7 @@ intention.category.comments=Comments
intention.category.groovy.style=Groovy-style
intention.category.control.flow=Control Flow
intention.category.groovy.declaration=Declaration
intention.category.groovy.other=Other
demorgans.law.intention.family.name=DeMorgan's Law
demorgans.intention.name1=Replace ''\\&\\&'' with ''||''
demorgans.intention.name2=Replace ''||'' with ''\\&\\&''
@@ -168,4 +169,6 @@ create.field.for.parameter=Create Field for Parameter
remove.unnecessary.escape.characters.intention.name=Remove unnecessary escape characters
remove.unnecessary.escape.characters.intention.family.name=Remove unnecessary escape characters
gr.break.string.on.line.breaks.intention.name=Break string on '\\n'
gr.break.string.on.line.breaks.intention.family.name=Break string on '\\n'
gr.break.string.on.line.breaks.intention.family.name=Break string on '\\n'
gr.create.missing.switch.branches.intention.name=Create missing 'switch' branches
gr.create.missing.switch.branches.intention.family.name=Create missing 'switch' branches
@@ -0,0 +1,111 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.intentions.other;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.intentions.base.Intention;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSwitchStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import java.util.Collections;
import java.util.List;
/**
* @author Max Medvedev
*/
public class GrCreateMissingSwitchBranchesIntention extends Intention {
@Override
protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
if (!(element instanceof GrSwitchStatement)) return;
final List<PsiEnumConstant> constants = findUnusedConstants((GrSwitchStatement)element);
if (constants.isEmpty()) return;
final PsiEnumConstant first = constants.get(0);
final PsiClass aClass = first.getContainingClass();
if (aClass == null) return;
String qName = aClass.getQualifiedName();
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
PsiElement anchor = findAnchor(element);
for (PsiEnumConstant constant : constants) {
final GrCaseSection section = factory.createSwitchSection("case " + qName + "." + constant.getName() + ":\n break");
final PsiElement added = element.addBefore(section, anchor);
element.addBefore(factory.createLineTerminator(1), anchor);
GrReferenceAdjuster.shortenReferences(added);
}
}
@Nullable
private static PsiElement findAnchor(PsiElement element) {
final PsiElement last = element.getLastChild();
if (last != null && last.getNode().getElementType() == GroovyTokenTypes.mRCURLY) return last;
return null;
}
@NotNull
@Override
protected PsiElementPredicate getElementPredicate() {
return new PsiElementPredicate() {
@Override
public boolean satisfiedBy(PsiElement element) {
if (!(element instanceof GrSwitchStatement)) return false;
final List<PsiEnumConstant> unused = findUnusedConstants((GrSwitchStatement)element);
return !unused.isEmpty();
}
};
}
private static List<PsiEnumConstant> findUnusedConstants(GrSwitchStatement switchStatement) {
final GrExpression condition = switchStatement.getCondition();
if (condition == null) return Collections.emptyList();
final PsiType type = condition.getType();
if (!(type instanceof PsiClassType)) return Collections.emptyList();
final PsiClass resolved = ((PsiClassType)type).resolve();
if (resolved == null || !resolved.isEnum()) return Collections.emptyList();
final PsiField[] fields = resolved.getFields();
final List<PsiEnumConstant> constants = ContainerUtil.findAll(fields, PsiEnumConstant.class);
final GrCaseSection[] sections = switchStatement.getCaseSections();
for (GrCaseSection section : sections) {
final GrExpression value = section.getCaseLabel().getValue();
if (value instanceof GrReferenceExpression) {
final PsiElement r = ((GrReferenceExpression)value).resolve();
constants.remove(r);
}
}
return constants;
}
}
@@ -93,7 +93,7 @@ public class Declaration implements GroovyElementTypes {
} else {
checkMarker.drop();
}
IElementType decl = VariableDefinitions.parseDefinitions(builder, isInClass, false, false, true, modifiersParsed, false, parser);
IElementType decl = VariableDefinitions.parseDefinitions(builder, isInClass, isInAnnotation, true, modifiersParsed, false, parser);
if (WRONGWAY.equals(decl)) {
return WRONGWAY;
@@ -115,7 +115,7 @@ public class Declaration implements GroovyElementTypes {
}
//current token isn't identifier
IElementType varDecl = VariableDefinitions.parse(builder, isInClass, modifiersParsed, parser);
IElementType varDecl = VariableDefinitions.parseDefinitions(builder, isInClass, isInAnnotation, false, modifiersParsed, true, parser);
if (WRONGWAY.equals(varDecl)) {
return WRONGWAY;
@@ -123,7 +123,8 @@ public class Declaration implements GroovyElementTypes {
return varDecl;
} else { //type was recognized, identifier here
//starts after type
IElementType varDeclarationTop = VariableDefinitions.parse(builder, isInClass, modifiersParsed, false, parser);
IElementType varDeclarationTop =
VariableDefinitions.parseDefinitions(builder, isInClass, isInAnnotation, false, modifiersParsed, false, parser);
if (WRONGWAY.equals(varDeclarationTop)) {
if (typeResult == mustBeType) {
@@ -138,7 +139,7 @@ public class Declaration implements GroovyElementTypes {
}
//starts before "type" identifier, here can't be tuple, because next token is identifier (we are in "type recognized" branch)
return VariableDefinitions.parse(builder, isInClass, modifiersParsed, false, parser);
return VariableDefinitions.parseDefinitions(builder, isInClass, isInAnnotation, false, modifiersParsed, false, parser);
} else {
checkMarker.drop();
return varDeclarationTop;
@@ -168,7 +169,7 @@ public class Declaration implements GroovyElementTypes {
}
}
IElementType varDef = VariableDefinitions.parseDefinitions(builder, isInClass, false, false, false, typeParsed, false, parser);
IElementType varDef = VariableDefinitions.parseDefinitions(builder, isInClass, isInAnnotation, false, typeParsed, false, parser);
if (varDef != WRONGWAY) {
return varDef;
}
@@ -27,7 +27,6 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.parameters.Par
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.TupleParse;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.AssignmentExpression;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.ConditionalExpression;
import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
/**
@@ -46,21 +45,14 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
*/
public class VariableDefinitions implements GroovyElementTypes {
public static IElementType parse(PsiBuilder builder, boolean isInClass, boolean hasModifiers, GroovyParser parser) {
return parseDefinitions(builder, isInClass, false, false, false, hasModifiers, true, parser);
}
public static IElementType parse(PsiBuilder builder, boolean isInClass, boolean hasModifiers, boolean canBeTuple, GroovyParser parser) {
return parseDefinitions(builder, isInClass, false, false, false, hasModifiers, canBeTuple, parser);
}
public static IElementType parseDefinitions(PsiBuilder builder,
boolean isInClass,
boolean isEnumConstantMember,
boolean isAnnotationMember,
boolean mustBeMethod,
boolean hasModifiers,
boolean canBeTuple, GroovyParser parser) {
boolean canBeTuple,
GroovyParser parser) {
boolean isLParen = builder.getTokenType() == mLPAREN;
boolean isStringName = builder.getTokenType() == mSTRING_LITERAL || builder.getTokenType() == mGSTRING_LITERAL;
@@ -106,18 +98,14 @@ public class VariableDefinitions implements GroovyElementTypes {
ParameterList.parse(builder, mRPAREN, parser);
if (isEnumConstantMember && !isStringName) {
builder.error(GroovyBundle.message("string.name.unexpected"));
}
ParserUtils.getToken(builder, mNLS);
if (!ParserUtils.getToken(builder, mRPAREN)) {
builder.error(GroovyBundle.message("rparen.expected"));
ThrowClause.parse(builder);
return METHOD_DEFINITION;
return isAnnotationMember ? ANNOTATION_METHOD : METHOD_DEFINITION;
}
if (builder.getTokenType() == kDEFAULT) {
if (isAnnotationMember && builder.getTokenType() == kDEFAULT) {
PsiBuilder.Marker defaultValueMarker = builder.mark();
ParserUtils.getToken(builder, kDEFAULT);
ParserUtils.getToken(builder, mNLS);
@@ -127,32 +115,33 @@ public class VariableDefinitions implements GroovyElementTypes {
}
defaultValueMarker.done(DEFAULT_ANNOTATION_VALUE);
ThrowClause.parse(builder); //every method must have a throws clause, so says the Java API
return ANNOTATION_METHOD;
}
if (ParserUtils.lookAhead(builder, mNLS, kTHROWS) || ParserUtils.lookAhead(builder, mNLS, mLCURLY)) {
ParserUtils.getToken(builder, mNLS);
}
if (isAnnotationMember && builder.getTokenType() == kTHROWS) {
builder.error(GroovyBundle.message("throws.clause.is.not.allowed.in.at.interface"));
}
ThrowClause.parse(builder);
if (builder.getTokenType() == mLCURLY || ParserUtils.lookAhead(builder, mNLS, mLCURLY)) {
ParserUtils.getToken(builder, mNLS);
if (isAnnotationMember) {
builder.error(GroovyBundle.message("separator.or.rcurly.expected"));
}
OpenOrClosableBlock.parseOpenBlock(builder, parser);
}
// if (isAnnotationMember && !NONE.equals(paramDeclList) && OPEN_BLOCK.equals(openBlock)) {
// builder.error(GroovyBundle.message("empty.parameter.list.expected"));
// }
return METHOD_DEFINITION;
return isAnnotationMember ? ANNOTATION_METHOD : METHOD_DEFINITION;
}
}
// a = b, c = d
PsiBuilder.Marker varAssMarker = builder.mark();
final IElementType declarator = parseDeclarator(builder, isLParen, hasModifiers);
final IElementType declarator = parseDeclarator(builder, isLParen);
if (declarator != WRONGWAY) {
final boolean wasAssingment = parseAssignment(builder, parser);
@@ -210,12 +199,12 @@ public class VariableDefinitions implements GroovyElementTypes {
}
}
private static IElementType parseDeclarator(PsiBuilder builder, boolean isTuple, boolean hasModifiers) {
private static IElementType parseDeclarator(PsiBuilder builder, boolean isTuple) {
if (!isTuple) {
if (builder.getTokenType() == mIDENT) {
ParserUtils.getToken(builder, mIDENT);
return mIDENT;
}
}
} else if (builder.getTokenType() == mLPAREN && isTuple) {
if (TupleParse.parseTuple(builder, TUPLE_DECLARATION, VARIABLE)) {
return TUPLE_DECLARATION;
@@ -241,12 +230,4 @@ public class VariableDefinitions implements GroovyElementTypes {
}
return false;
}
// private static boolean parseAnnotationMemberValueInitializer(PsiBuilder builder) {
// return !WRONGWAY.equals(Annotation.parse(builder)) || !WRONGWAY.equals(ConditionalExpression.parse(builder));
// }
// public static GroovyElementType parseAnnotationMember(PsiBuilder builder) {
// return parseDefinitions(builder, false, false, true);
// }
}
@@ -200,7 +200,10 @@ public class TypeDefinition implements GroovyElementTypes {
while (!builder.eof() && builder.getTokenType() != mRCURLY) {
if (!parseAnnotationMember(builder, parser)) builder.advanceLexer();
Separators.parse(builder);
if (builder.getTokenType() == mRCURLY) break;
if (!Separators.parse(builder)) {
builder.error(GroovyBundle.message("separator.or.rcurly.expected"));
}
}
ParserUtils.getToken(builder, mRCURLY, GroovyBundle.message("rcurly.expected"));
@@ -313,7 +316,10 @@ public class TypeDefinition implements GroovyElementTypes {
while (!builder.eof() && builder.getTokenType() != mRCURLY) {
if (!InterfaceMember.parse(builder, interfaceName, parser)) builder.advanceLexer();
Separators.parse(builder);
if (builder.getTokenType() == mRCURLY) break;
if (!Separators.parse(builder)) {
builder.error(GroovyBundle.message("separator.or.rcurly.expected"));
}
}
ParserUtils.getToken(builder, mRCURLY, GroovyBundle.message("rcurly.expected"));
@@ -52,6 +52,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMe
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.types.*;
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrDisjunctionTypeElementImpl;
/**
* @author ven
@@ -244,16 +245,24 @@ public abstract class GroovyElementVisitor {
visitExpression(listOrMap);
}
public void visitArrayTypeElement(GrArrayTypeElement typeElement) {
public void visitTypeElement(GrTypeElement typeElement) {
visitElement(typeElement);
}
public void visitArrayTypeElement(GrArrayTypeElement typeElement) {
visitTypeElement(typeElement);
}
public void visitBuiltinTypeElement(GrBuiltInTypeElement typeElement) {
visitElement(typeElement);
visitTypeElement(typeElement);
}
public void visitClassTypeElement(GrClassTypeElement typeElement) {
visitElement(typeElement);
visitTypeElement(typeElement);
}
public void visitDisjunctionTypeElement(GrDisjunctionTypeElement disjunctionTypeElement) {
visitTypeElement(disjunctionTypeElement);
}
public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
@@ -36,6 +36,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
@@ -67,6 +68,8 @@ public abstract class GroovyPsiElementFactory implements JVMElementFactory {
public abstract GrModifierList createModifierList(String text);
public abstract GrCaseSection createSwitchSection(String text);
public static GroovyPsiElementFactory getInstance(Project project) {
return ServiceManager.getService(project, GroovyPsiElementFactory.class);
}
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.api.statements;
import com.intellij.psi.PsiAnnotationMemberValue;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue;
@@ -23,7 +24,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.
* User: Dmitry.Krasilschikov
* Date: 04.06.2007
*/
public interface GrDefaultAnnotationValue extends GroovyPsiElement {
public interface GrDefaultAnnotationValue extends GroovyPsiElement, PsiAnnotationMemberValue {
@Nullable
GrAnnotationMemberValue getDefaultValue();
}
@@ -15,6 +15,7 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members;
import com.intellij.psi.PsiAnnotationMethod;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrDefaultAnnotationValue;
@@ -22,7 +23,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrDefaultAnnotationV
* User: Dmitry.Krasilschikov
* Date: 04.06.2007
*/
public interface GrAnnotationMethod extends GrMethod {
public interface GrAnnotationMethod extends GrMethod, PsiAnnotationMethod {
@Nullable
GrDefaultAnnotationValue getDefaultAnnotationValue();
GrDefaultAnnotationValue getDefaultValue();
}
@@ -49,6 +49,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
@@ -692,6 +693,18 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
return method.getModifierList();
}
@Override
public GrCaseSection createSwitchSection(String text) {
final GrStatement statement = createStatementFromText("switch (a) {\n" + text + "\n}");
if (!(statement instanceof GrSwitchStatement)) {
throw new IncorrectOperationException("Cannot create switch section from text: " + text);
}
final GrCaseSection[] sections = ((GrSwitchStatement)statement).getCaseSections();
if (sections.length != 1) throw new IncorrectOperationException("Cannot create switch section from text: " + text);
return sections[0];
}
public GrImportStatement createImportStatementFromText(String qName, boolean isStatic, boolean isOnDemand, String alias) {
final String text = "import " + (isStatic ? "static " : "") + qName + (isOnDemand ? ".*" : "") +
(alias != null && alias.length() > 0 ? " as " + alias : "");
@@ -56,6 +56,11 @@ public class GrAnnotationNameValuePairImpl extends GroovyPsiElementImpl implemen
return nameId != null ? nameId.getText() : null;
}
@Override
public String getLiteralValue() {
return null;
}
@Nullable
public PsiElement getNameIdentifierGroovy() {
return findChildByType(GroovyTokenTypes.mIDENT);
@@ -24,7 +24,9 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ComparatorUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import gnu.trove.THashMap;
import gnu.trove.TIntObjectHashMap;
@@ -36,6 +38,9 @@ import org.jetbrains.plugins.groovy.lang.psi.GrTypeConverter;
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.SpreadState;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue;
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
@@ -752,4 +757,36 @@ public class TypesUtil {
return factory.createType(collection, item);
}
@Nullable
public static PsiType inferAnnotationMemberValueType(GrAnnotationMemberValue value) {
if (value instanceof GrExpression) {
return ((GrExpression)value).getType();
}
else if (value instanceof GrAnnotation) {
final PsiElement resolved = ((GrAnnotation)value).getClassReference().resolve();
if (resolved instanceof PsiClass) {
return JavaPsiFacade.getElementFactory(value.getProject()).createType((PsiClass)resolved, PsiSubstitutor.EMPTY);
}
return null;
}
else if (value instanceof GrAnnotationArrayInitializer) {
return getTupleByAnnotationArrayInitializer((GrAnnotationArrayInitializer)value);
}
return null;
}
public static PsiType getTupleByAnnotationArrayInitializer(GrAnnotationArrayInitializer value) {
final GrAnnotationMemberValue[] initializers = value.getInitializers();
PsiType[] types = ContainerUtil.map(initializers, new Function<GrAnnotationMemberValue, PsiType>() {
@Override
public PsiType fun(GrAnnotationMemberValue value) {
return inferAnnotationMemberValueType(value);
}
}, new PsiType[initializers.length]);
return new GrTupleType(types, JavaPsiFacade.getInstance(value.getProject()), value.getResolveScope());
}
}
@@ -54,7 +54,7 @@ public class GrAnnotationMethodImpl extends GrMethodBaseImpl implements GrAnnota
}
@Override
public GrDefaultAnnotationValue getDefaultAnnotationValue() {
public GrDefaultAnnotationValue getDefaultValue() {
return findChildByClass(GrDefaultAnnotationValue.class);
}
}
@@ -111,10 +111,7 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase<GrMethodStub> i
@Nullable
public GrOpenBlock getBlock() {
for (PsiElement cur = this.getFirstChild(); cur != null; cur = cur.getNextSibling()) {
if (cur instanceof GrOpenBlock) return (GrOpenBlock)cur;
}
return null;
return findChildByClass(GrOpenBlock.class);
}
public void setBlock(GrCodeBlock newBlock) {
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrDisjunctionTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementImpl;
@@ -44,6 +45,11 @@ public class GrDisjunctionTypeElementImpl extends GroovyPsiElementImpl implement
return findChildrenByClass(GrTypeElement.class);
}
@Override
public void accept(GroovyElementVisitor visitor) {
visitor.visitDisjunctionTypeElement(this);
}
@NotNull
@Override
public PsiType getType() {
@@ -131,7 +131,7 @@ public class ClassItemGeneratorImpl implements ClassItemGenerator {
GenerationUtil.writeParameterList(builder, method.getParameterList().getParameters(), classNameProvider, context);
if (method instanceof GrAnnotationMethod) {
GrDefaultAnnotationValue defaultAnnotationValue = ((GrAnnotationMethod)method).getDefaultAnnotationValue();
GrDefaultAnnotationValue defaultAnnotationValue = ((GrAnnotationMethod)method).getDefaultValue();
if (defaultAnnotationValue!=null) {
builder.append("default ");
GrAnnotationMemberValue defaultValue = defaultAnnotationValue.getDefaultValue();
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiMethodUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
@@ -30,12 +31,18 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
*/
public class GroovyRunnerUtil {
@Nullable
public static PsiClass getRunningClass(PsiElement element) {
public static PsiClass getRunningClass(@Nullable PsiElement element) {
if (element == null) return null;
final PsiFile file = element.getContainingFile();
if (!(file instanceof GroovyFile)) return null;
for (PsiClass clazz = PsiTreeUtil.getParentOfType(element, PsiClass.class);
clazz != null;
clazz = PsiTreeUtil.getParentOfType(clazz, PsiClass.class)) {
if (canBeRunByGroovy(clazz)) return clazz;
}
if (((GroovyFile)file).isScript()) return ((GroovyFile)file).getScriptClass();
final PsiClass[] classes = ((GroovyFile)file).getClasses();
@@ -0,0 +1,57 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.intentions
import org.jetbrains.plugins.groovy.util.TestUtils;
/**
* @author Max Medvedev
*/
public class GrCreateMissingSwitchBranchesTest extends GrIntentionTestCase {
private static final String HINT = GroovyIntentionsBundle.message("gr.create.missing.switch.branches.intention.name")
final String basePath = "${TestUtils.testDataPath}intentions/constructorMatchingSuper/"
void testSimple() {
doTextTest('''\
enum E {
a, b, c
}
E e = E.a
switch (e) {
<caret>
}
''', HINT, '''\
enum E {
a, b, c
}
E e = E.a
switch (e) {
<caret>
case E.a:
break
case E.b:
break
case E.c:
break
}
''')
}
}
@@ -1242,6 +1242,79 @@ import java.util.List
print Component
print List
''')
}
void testIncompatibleTypeOfImplicitGetter() {
testHighlighting('''\
abstract class Base {
abstract String getFoo()
}
class Inheritor extends Base {
final <error descr="The return type of java.lang.Object getFoo() in Inheritor is incompatible with java.lang.String getFoo() in Base">foo</error> = '3'
}''')
}
void testIncompatibleTypeOfInheritedMethod() {
testHighlighting('''\
abstract class Base {
abstract String getFoo()
}
class Inheritor extends Base {
def <error descr="The return type of java.lang.Object getFoo() in Inheritor is incompatible with java.lang.String getFoo() in Base">getFoo</error>() {''}
}''')
}
void testIncompatibleTypeOfInheritedMethod2() {
testHighlighting('''\
abstract class Base {
abstract String getFoo()
}
class Inheritor extends Base {
<error descr="The return type of java.lang.Object getFoo() in Inheritor is incompatible with java.lang.String getFoo() in Base">Object</error> getFoo() {''}
}''')
}
void testIncompatibleTypeOfInheritedMethodInAnonymous() {
testHighlighting('''\
abstract class Base {
abstract String getFoo()
}
new Base() {
<error descr="The return type of java.lang.Object getFoo() in anonymous class derived from Base is incompatible with java.lang.String getFoo() in Base">Object</error> getFoo() {''}
}''')
}
void testAnnotationArgs() {
testHighlighting('''\
@interface Int {
int value()
String s() default 'a'
}
@Int(<error descr="Cannot assign 'String' to 'int'">'a'</error>) def foo(){}
@Int(2) def bar(){}
@Int(value = 2) def c(){}
@Int(value = 3, s = <error descr="Cannot assign 'Integer' to 'String'">4</error>) def x(){}
@Int(value = 3, s = '4') def y(){}
''')
}
void testDefaultAttributeValue() {
testHighlighting('''\
@interface Int {
int value1() default 2
String value2() default <error descr="Cannot assign 'Integer' to 'String'">2</error>
String value3()
}
''')
}
}