mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+4
-3
@@ -857,12 +857,13 @@ public class AsmCodeGenerator {
|
||||
}
|
||||
pushBorderProperties(container, generator, borderTitle, componentLocal);
|
||||
|
||||
if (Boolean.valueOf(System.getProperty("idea.is.internal")).booleanValue()) {
|
||||
container.getDelegeeClientProperties().put(ourBorderFactoryClientProperty, StringDescriptor.create("com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"));
|
||||
}
|
||||
|
||||
Type borderFactoryType = ourBorderFactoryType;
|
||||
StringDescriptor borderFactoryValue = (StringDescriptor)container.getDelegeeClientProperties().get(ourBorderFactoryClientProperty);
|
||||
if (borderFactoryValue == null && Boolean.valueOf(System.getProperty("idea.is.internal")).booleanValue()) {
|
||||
borderFactoryValue = StringDescriptor.create("com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent");
|
||||
container.getDelegeeClientProperties().put(ourBorderFactoryClientProperty, borderFactoryValue);
|
||||
}
|
||||
if (borderFactoryValue != null && borderFactoryValue.getValue().length() != 0) {
|
||||
borderFactoryType = typeFromClassName(borderFactoryValue.getValue());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a method or constructor reference.
|
||||
*/
|
||||
public interface PsiMethodReferenceExpression extends PsiReferenceExpression {
|
||||
/**
|
||||
* Returns the type element used as the qualifier of the reference.
|
||||
*
|
||||
* @return the qualifier, or null if the reference is qualified by expression.
|
||||
*/
|
||||
@Nullable
|
||||
PsiTypeElement getQualifierType();
|
||||
}
|
||||
@@ -321,6 +321,7 @@ public class ExpressionParser {
|
||||
|
||||
private enum BreakPoint {P1, P2, P3, P4}
|
||||
|
||||
// todo[r.sh] make 'this', 'super' and 'class' reference expressions
|
||||
@Nullable
|
||||
private PsiBuilder.Marker parsePrimary(final PsiBuilder builder, @Nullable final BreakPoint breakPoint, final int breakOffset) {
|
||||
PsiBuilder.Marker startMarker = builder.mark();
|
||||
@@ -350,7 +351,7 @@ public class ExpressionParser {
|
||||
final int offset = builder.getCurrentOffset();
|
||||
startMarker.rollbackTo();
|
||||
|
||||
final PsiBuilder.Marker classObjAccess = parseClassObjectAccess(builder);
|
||||
final PsiBuilder.Marker classObjAccess = parseClassAccessOrMethodReference(builder);
|
||||
if (classObjAccess == null || builder.getCurrentOffset() < offset) {
|
||||
copy.rollbackTo();
|
||||
return parsePrimary(builder, BreakPoint.P1, offset);
|
||||
@@ -466,7 +467,7 @@ public class ExpressionParser {
|
||||
final PsiBuilder.Marker copy = startMarker.precede();
|
||||
startMarker.rollbackTo();
|
||||
|
||||
final PsiBuilder.Marker classObjAccess = parseClassObjectAccess(builder);
|
||||
final PsiBuilder.Marker classObjAccess = parseClassAccessOrMethodReference(builder);
|
||||
if (classObjAccess == null || builder.getCurrentOffset() <= pos) {
|
||||
copy.rollbackTo();
|
||||
return parsePrimary(builder, BreakPoint.P4, -1);
|
||||
@@ -498,6 +499,9 @@ public class ExpressionParser {
|
||||
expr = arrayAccess;
|
||||
}
|
||||
}
|
||||
else if (tokenType == JavaTokenType.DOUBLE_COLON) {
|
||||
return parseMethodReference(builder, startMarker);
|
||||
}
|
||||
else {
|
||||
startMarker.drop();
|
||||
return expr;
|
||||
@@ -515,6 +519,7 @@ public class ExpressionParser {
|
||||
literal.done(JavaElementType.LITERAL_EXPRESSION);
|
||||
return literal;
|
||||
}
|
||||
|
||||
if (tokenType == JavaTokenType.LPARENTH) {
|
||||
final PsiBuilder.Marker parenth = builder.mark();
|
||||
builder.advanceLexer();
|
||||
@@ -533,12 +538,25 @@ public class ExpressionParser {
|
||||
parenth.done(JavaElementType.PARENTH_EXPRESSION);
|
||||
return parenth;
|
||||
}
|
||||
|
||||
if (tokenType == JavaTokenType.LBRACE) {
|
||||
return parseArrayInitializer(builder);
|
||||
}
|
||||
|
||||
if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType) || tokenType == JavaTokenType.IDENTIFIER) {
|
||||
final boolean primitive = tokenType != JavaTokenType.IDENTIFIER;
|
||||
final PsiBuilder.Marker mark = builder.mark();
|
||||
|
||||
final ReferenceParser.TypeInfo typeInfo = myReferenceParser.parseTypeInfo(builder, 0);
|
||||
if (typeInfo != null && (primitive || !typeInfo.hasErrors && typeInfo.isParameterized)) {
|
||||
final PsiBuilder.Marker result = continueClassAccessOrMethodReference(builder, mark, primitive);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
mark.rollbackTo();
|
||||
}
|
||||
|
||||
PsiBuilder.Marker annotation = null;
|
||||
final PsiBuilder.Marker beforeAnnotation = builder.mark();
|
||||
if (tokenType == JavaTokenType.AT) {
|
||||
annotation = myDeclarationParser.parseAnnotations(builder);
|
||||
tokenType = builder.getTokenType();
|
||||
@@ -558,17 +576,13 @@ public class ExpressionParser {
|
||||
|
||||
builder.advanceLexer();
|
||||
refExpr.done(JavaElementType.REFERENCE_EXPRESSION);
|
||||
beforeAnnotation.drop();
|
||||
return refExpr;
|
||||
}
|
||||
|
||||
if (annotation != null) {
|
||||
beforeAnnotation.rollbackTo();
|
||||
annotation.rollbackTo();
|
||||
tokenType = builder.getTokenType();
|
||||
}
|
||||
else {
|
||||
beforeAnnotation.drop();
|
||||
}
|
||||
|
||||
PsiBuilder.Marker expr = null;
|
||||
if (tokenType == JavaTokenType.LT) {
|
||||
@@ -599,12 +613,10 @@ public class ExpressionParser {
|
||||
: JavaElementType.SUPER_EXPRESSION);
|
||||
return expr;
|
||||
}
|
||||
|
||||
if (tokenType == JavaTokenType.NEW_KEYWORD) {
|
||||
return parseNew(builder, null);
|
||||
}
|
||||
if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) {
|
||||
return parseClassObjectAccess(builder);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -745,27 +757,47 @@ public class ExpressionParser {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiBuilder.Marker parseClassObjectAccess(final PsiBuilder builder) {
|
||||
private PsiBuilder.Marker parseClassAccessOrMethodReference(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker expr = builder.mark();
|
||||
|
||||
final boolean primitive = ElementType.PRIMITIVE_TYPE_BIT_SET.contains(builder.getTokenType());
|
||||
if (myReferenceParser.parseType(builder, 0) == null) {
|
||||
expr.drop();
|
||||
return null;
|
||||
}
|
||||
|
||||
if (builder.getTokenType() != JavaTokenType.DOT) {
|
||||
expr.rollbackTo();
|
||||
return null;
|
||||
final PsiBuilder.Marker result = continueClassAccessOrMethodReference(builder, expr, primitive);
|
||||
if (result == null) expr.rollbackTo();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiBuilder.Marker continueClassAccessOrMethodReference(final PsiBuilder builder,
|
||||
final PsiBuilder.Marker expr,
|
||||
final boolean primitive) {
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (tokenType == JavaTokenType.DOT) {
|
||||
return parseClassObjectAccess(builder, expr, primitive);
|
||||
}
|
||||
PsiBuilder.Marker afterType = builder.mark();
|
||||
else if (tokenType == JavaTokenType.DOUBLE_COLON) {
|
||||
return parseMethodReference(builder, expr);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiBuilder.Marker parseClassObjectAccess(PsiBuilder builder, PsiBuilder.Marker expr, boolean primitive) {
|
||||
final PsiBuilder.Marker mark = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
if (builder.getTokenType() == JavaTokenType.CLASS_KEYWORD) {
|
||||
afterType.drop();
|
||||
mark.drop();
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else {
|
||||
afterType.rollbackTo();
|
||||
if (!primitive) return null;
|
||||
mark.rollbackTo();
|
||||
builder.error(".class expected");
|
||||
}
|
||||
|
||||
@@ -773,6 +805,20 @@ public class ExpressionParser {
|
||||
return expr;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiBuilder.Marker parseMethodReference(final PsiBuilder builder, final PsiBuilder.Marker start) {
|
||||
builder.advanceLexer();
|
||||
|
||||
myReferenceParser.parseReferenceParameterList(builder, false, false);
|
||||
|
||||
if (!expect(builder, JavaTokenType.IDENTIFIER) && !expect(builder, JavaTokenType.NEW_KEYWORD)) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
|
||||
start.done(JavaElementType.METHOD_REF_EXPRESSION);
|
||||
return start;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiBuilder.Marker parseArgumentList(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker list = builder.mark();
|
||||
|
||||
@@ -29,13 +29,12 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
|
||||
|
||||
TokenSet KEYWORD_BIT_SET = TokenSet.create(
|
||||
ABSTRACT_KEYWORD, ASSERT_KEYWORD, BOOLEAN_KEYWORD, BREAK_KEYWORD, BYTE_KEYWORD, CASE_KEYWORD, CATCH_KEYWORD, CHAR_KEYWORD,
|
||||
CLASS_KEYWORD,
|
||||
CONST_KEYWORD, CONTINUE_KEYWORD, DEFAULT_KEYWORD, DO_KEYWORD, DOUBLE_KEYWORD, ELSE_KEYWORD, ENUM_KEYWORD, EXTENDS_KEYWORD,
|
||||
FINAL_KEYWORD,
|
||||
FINALLY_KEYWORD, FLOAT_KEYWORD, FOR_KEYWORD, GOTO_KEYWORD, IF_KEYWORD, IMPLEMENTS_KEYWORD, IMPORT_KEYWORD, INSTANCEOF_KEYWORD,
|
||||
INT_KEYWORD, INTERFACE_KEYWORD, LONG_KEYWORD, NATIVE_KEYWORD, NEW_KEYWORD, PACKAGE_KEYWORD, PRIVATE_KEYWORD, PROTECTED_KEYWORD,
|
||||
PUBLIC_KEYWORD, RETURN_KEYWORD, SHORT_KEYWORD, SUPER_KEYWORD, STATIC_KEYWORD, STRICTFP_KEYWORD, SWITCH_KEYWORD, SYNCHRONIZED_KEYWORD,
|
||||
THIS_KEYWORD, THROW_KEYWORD, THROWS_KEYWORD, TRANSIENT_KEYWORD, TRY_KEYWORD, VOID_KEYWORD, VOLATILE_KEYWORD, WHILE_KEYWORD);
|
||||
CLASS_KEYWORD, CONST_KEYWORD, CONTINUE_KEYWORD, DEFAULT_KEYWORD, DO_KEYWORD, DOUBLE_KEYWORD, ELSE_KEYWORD, ENUM_KEYWORD,
|
||||
EXTENDS_KEYWORD, FINAL_KEYWORD, FINALLY_KEYWORD, FLOAT_KEYWORD, FOR_KEYWORD, GOTO_KEYWORD, IF_KEYWORD, IMPLEMENTS_KEYWORD,
|
||||
IMPORT_KEYWORD, INSTANCEOF_KEYWORD, INT_KEYWORD, INTERFACE_KEYWORD, LONG_KEYWORD, NATIVE_KEYWORD, NEW_KEYWORD, PACKAGE_KEYWORD,
|
||||
PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, RETURN_KEYWORD, SHORT_KEYWORD, SUPER_KEYWORD, STATIC_KEYWORD, STRICTFP_KEYWORD,
|
||||
SWITCH_KEYWORD, SYNCHRONIZED_KEYWORD, THIS_KEYWORD, THROW_KEYWORD, THROWS_KEYWORD, TRANSIENT_KEYWORD, TRY_KEYWORD, VOID_KEYWORD,
|
||||
VOLATILE_KEYWORD, WHILE_KEYWORD);
|
||||
|
||||
TokenSet LITERAL_BIT_SET = TokenSet.create(TRUE_KEYWORD, FALSE_KEYWORD, NULL_KEYWORD);
|
||||
|
||||
@@ -45,33 +44,31 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
|
||||
PLUSEQ, MINUSEQ, ASTERISKEQ, DIVEQ, ANDEQ, OREQ, XOREQ, PERCEQ, LTLTEQ, GTGTEQ, GTGTGTEQ);
|
||||
|
||||
TokenSet MODIFIER_BIT_SET = TokenSet.create(
|
||||
PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, STATIC_KEYWORD, ABSTRACT_KEYWORD, FINAL_KEYWORD, NATIVE_KEYWORD, SYNCHRONIZED_KEYWORD,
|
||||
STRICTFP_KEYWORD, TRANSIENT_KEYWORD, VOLATILE_KEYWORD);
|
||||
PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, STATIC_KEYWORD, ABSTRACT_KEYWORD, FINAL_KEYWORD, NATIVE_KEYWORD,
|
||||
SYNCHRONIZED_KEYWORD, STRICTFP_KEYWORD, TRANSIENT_KEYWORD, VOLATILE_KEYWORD);
|
||||
|
||||
TokenSet PRIMITIVE_TYPE_BIT_SET = TokenSet.create(
|
||||
BOOLEAN_KEYWORD, BYTE_KEYWORD, SHORT_KEYWORD, INT_KEYWORD, LONG_KEYWORD, CHAR_KEYWORD, FLOAT_KEYWORD, DOUBLE_KEYWORD, VOID_KEYWORD);
|
||||
|
||||
TokenSet EXPRESSION_BIT_SET = TokenSet.create(
|
||||
REFERENCE_EXPRESSION, LITERAL_EXPRESSION, THIS_EXPRESSION, SUPER_EXPRESSION, PARENTH_EXPRESSION, METHOD_CALL_EXPRESSION,
|
||||
TYPE_CAST_EXPRESSION, PREFIX_EXPRESSION, POSTFIX_EXPRESSION, BINARY_EXPRESSION, POLYADIC_EXPRESSION, CONDITIONAL_EXPRESSION, ASSIGNMENT_EXPRESSION,
|
||||
NEW_EXPRESSION, ARRAY_ACCESS_EXPRESSION, ARRAY_INITIALIZER_EXPRESSION, INSTANCE_OF_EXPRESSION, CLASS_OBJECT_ACCESS_EXPRESSION,
|
||||
EMPTY_EXPRESSION);
|
||||
TYPE_CAST_EXPRESSION, PREFIX_EXPRESSION, POSTFIX_EXPRESSION, BINARY_EXPRESSION, POLYADIC_EXPRESSION, CONDITIONAL_EXPRESSION,
|
||||
ASSIGNMENT_EXPRESSION, NEW_EXPRESSION, ARRAY_ACCESS_EXPRESSION, ARRAY_INITIALIZER_EXPRESSION, INSTANCE_OF_EXPRESSION,
|
||||
CLASS_OBJECT_ACCESS_EXPRESSION, METHOD_REF_EXPRESSION, EMPTY_EXPRESSION);
|
||||
|
||||
TokenSet ANNOTATION_MEMBER_VALUE_BIT_SET = TokenSet.orSet(EXPRESSION_BIT_SET,
|
||||
TokenSet.create(ANNOTATION, ANNOTATION_ARRAY_INITIALIZER));
|
||||
|
||||
TokenSet ARRAY_DIMENSION_BIT_SET = TokenSet.create(
|
||||
REFERENCE_EXPRESSION, LITERAL_EXPRESSION, THIS_EXPRESSION, SUPER_EXPRESSION, PARENTH_EXPRESSION, METHOD_CALL_EXPRESSION,
|
||||
TYPE_CAST_EXPRESSION, PREFIX_EXPRESSION, POSTFIX_EXPRESSION, BINARY_EXPRESSION, POLYADIC_EXPRESSION, CONDITIONAL_EXPRESSION, ASSIGNMENT_EXPRESSION,
|
||||
NEW_EXPRESSION, ARRAY_ACCESS_EXPRESSION, INSTANCE_OF_EXPRESSION, CLASS_OBJECT_ACCESS_EXPRESSION, EMPTY_EXPRESSION);
|
||||
TYPE_CAST_EXPRESSION, PREFIX_EXPRESSION, POSTFIX_EXPRESSION, BINARY_EXPRESSION, POLYADIC_EXPRESSION, CONDITIONAL_EXPRESSION,
|
||||
ASSIGNMENT_EXPRESSION, NEW_EXPRESSION, ARRAY_ACCESS_EXPRESSION, INSTANCE_OF_EXPRESSION, CLASS_OBJECT_ACCESS_EXPRESSION,
|
||||
EMPTY_EXPRESSION);
|
||||
|
||||
TokenSet JAVA_STATEMENT_BIT_SET = TokenSet.create(
|
||||
EMPTY_STATEMENT, BLOCK_STATEMENT, EXPRESSION_STATEMENT, EXPRESSION_LIST_STATEMENT,
|
||||
DECLARATION_STATEMENT, IF_STATEMENT, WHILE_STATEMENT, FOR_STATEMENT, FOREACH_STATEMENT,
|
||||
DO_WHILE_STATEMENT, SWITCH_STATEMENT, SWITCH_LABEL_STATEMENT, BREAK_STATEMENT,
|
||||
CONTINUE_STATEMENT, RETURN_STATEMENT, THROW_STATEMENT, SYNCHRONIZED_STATEMENT,
|
||||
TRY_STATEMENT, LABELED_STATEMENT, ASSERT_STATEMENT
|
||||
);
|
||||
EMPTY_STATEMENT, BLOCK_STATEMENT, EXPRESSION_STATEMENT, EXPRESSION_LIST_STATEMENT, DECLARATION_STATEMENT, IF_STATEMENT,
|
||||
WHILE_STATEMENT, FOR_STATEMENT, FOREACH_STATEMENT, DO_WHILE_STATEMENT, SWITCH_STATEMENT, SWITCH_LABEL_STATEMENT, BREAK_STATEMENT,
|
||||
CONTINUE_STATEMENT, RETURN_STATEMENT, THROW_STATEMENT, SYNCHRONIZED_STATEMENT, TRY_STATEMENT, LABELED_STATEMENT, ASSERT_STATEMENT);
|
||||
|
||||
TokenSet TYPES_BIT_SET = TokenSet.create(TYPE);
|
||||
TokenSet IMPORT_STATEMENT_BIT_SET = TokenSet.create(IMPORT_STATEMENT);
|
||||
@@ -79,7 +76,6 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
|
||||
TokenSet IMPORT_STATEMENT_BASE_BIT_SET = TokenSet.create(IMPORT_STATEMENT, IMPORT_STATIC_STATEMENT);
|
||||
TokenSet CLASS_KEYWORD_BIT_SET = TokenSet.create(CLASS_KEYWORD, INTERFACE_KEYWORD, ENUM_KEYWORD);
|
||||
TokenSet MEMBER_BIT_SET = TokenSet.create(CLASS, FIELD, ENUM_CONSTANT, METHOD, ANNOTATION_METHOD);
|
||||
TokenSet FULL_MEMBER_BIT_SET = TokenSet.orSet(MEMBER_BIT_SET,
|
||||
TokenSet.create(CLASS_INITIALIZER));
|
||||
TokenSet FULL_MEMBER_BIT_SET = TokenSet.orSet(MEMBER_BIT_SET, TokenSet.create(CLASS_INITIALIZER));
|
||||
TokenSet ANNOTATIONS = TokenSet.create(ANNOTATION);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -104,6 +104,7 @@ public interface JavaElementType {
|
||||
IElementType INSTANCE_OF_EXPRESSION = new JavaCompositeElementType("INSTANCE_OF_EXPRESSION", PsiInstanceOfExpressionImpl.class);
|
||||
IElementType CLASS_OBJECT_ACCESS_EXPRESSION = new JavaCompositeElementType("CLASS_OBJECT_ACCESS_EXPRESSION", PsiClassObjectAccessExpressionImpl.class);
|
||||
IElementType EMPTY_EXPRESSION = new JavaCompositeElementType("EMPTY_EXPRESSION", PsiEmptyExpressionImpl.class, true);
|
||||
IElementType METHOD_REF_EXPRESSION = new JavaCompositeElementType("METHOD_REF_EXPRESSION", PsiMethodReferenceExpressionImpl.class);
|
||||
IElementType EXPRESSION_LIST = new JavaCompositeElementType("EXPRESSION_LIST", PsiExpressionListImpl.class, true);
|
||||
IElementType EMPTY_STATEMENT = new JavaCompositeElementType("EMPTY_STATEMENT", PsiEmptyStatementImpl.class);
|
||||
IElementType BLOCK_STATEMENT = new JavaCompositeElementType("BLOCK_STATEMENT", PsiBlockStatementImpl.class);
|
||||
|
||||
+111
@@ -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 com.intellij.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase implements PsiMethodReferenceExpression {
|
||||
private static Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiMethodReferenceExpressionImpl");
|
||||
|
||||
public PsiMethodReferenceExpressionImpl() {
|
||||
super(JavaElementType.METHOD_REF_EXPRESSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiTypeElement getQualifierType() {
|
||||
final PsiElement qualifier = getQualifier();
|
||||
return qualifier instanceof PsiTypeElement ? (PsiTypeElement)qualifier : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiExpression getQualifierExpression() {
|
||||
final PsiElement qualifier = getQualifier();
|
||||
return qualifier instanceof PsiExpression ? (PsiExpression)qualifier : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType getType() {
|
||||
// todo[r.sh]: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getReferenceNameElement() {
|
||||
final PsiElement element = getLastChild();
|
||||
return element instanceof PsiIdentifier || PsiUtil.isJavaToken(element, JavaTokenType.NEW_KEYWORD) ? element : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processVariants(final PsiScopeProcessor processor) {
|
||||
// todo[r.sh]: implement
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JavaResolveResult[] multiResolve(final boolean incompleteCode) {
|
||||
// todo[r.sh]: implement
|
||||
return JavaResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getQualifier() {
|
||||
final PsiElement element = getFirstChild();
|
||||
return element instanceof PsiExpression || element instanceof PsiTypeElement ? element : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
final PsiElement element = getReferenceNameElement();
|
||||
if (element != null) return new TextRange(element.getStartOffsetInParent(), element.getTextLength());
|
||||
final PsiElement colons = findPsiChildByType(JavaTokenType.DOUBLE_COLON);
|
||||
if (colons != null) return new TextRange(colons.getStartOffsetInParent(), colons.getTextLength());
|
||||
LOG.error(getText());
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getCanonicalText() {
|
||||
return getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(final PsiElement element) {
|
||||
if (!(element instanceof PsiMethod)) return false;
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
|
||||
final PsiElement nameElement = getReferenceNameElement();
|
||||
if (nameElement instanceof PsiIdentifier) {
|
||||
if (!nameElement.getText().equals(method.getName())) return false;
|
||||
}
|
||||
else if (PsiUtil.isJavaToken(nameElement, JavaTokenType.NEW_KEYWORD)) {
|
||||
if (!method.isConstructor()) return false;
|
||||
}
|
||||
|
||||
return element.getManager().areElementsEquivalent(element, resolve());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiMethodReferenceExpression:" + getText();
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class PsiReferenceExpressionBase extends ExpressionPsiElement implements PsiReferenceExpression {
|
||||
public PsiReferenceExpressionBase(@NotNull final IElementType type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement bindToElementViaStaticImport(@NotNull final PsiClass qualifierClass) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQualifierExpression(@Nullable PsiExpression newQualifier) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
return advancedResolve(false).getElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
throw new IncorrectOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(final PsiElement element) {
|
||||
return element.getManager().areElementsEquivalent(element, resolve());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object[] getVariants() {
|
||||
// this reference's variants are rather obtained with processVariants()
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference getReference() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JavaResolveResult advancedResolve(boolean incompleteCode) {
|
||||
final JavaResolveResult[] results = multiResolve(incompleteCode);
|
||||
return results.length == 1 ? results[0] : JavaResolveResult.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferenceName() {
|
||||
final PsiElement element = getReferenceNameElement();
|
||||
return element != null ? element.getText() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReferenceParameterList getParameterList() {
|
||||
return PsiTreeUtil.getChildOfType(this, PsiReferenceParameterList.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiType[] getTypeParameters() {
|
||||
final PsiReferenceParameterList parameterList = getParameterList();
|
||||
return parameterList != null ? parameterList.getTypeArguments() : PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isQualified() {
|
||||
return getQualifier() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQualifiedName() {
|
||||
return getCanonicalText();
|
||||
}
|
||||
}
|
||||
+11
-71
@@ -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.
|
||||
@@ -60,7 +60,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements PsiReferenceExpression, SourceJavaCodeReference {
|
||||
public class PsiReferenceExpressionImpl extends PsiReferenceExpressionBase implements PsiReferenceExpression, SourceJavaCodeReference {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl");
|
||||
|
||||
private volatile String myCachedQName = null;
|
||||
@@ -108,7 +108,8 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
}
|
||||
else {
|
||||
PsiManagerEx manager = getManager();
|
||||
PsiReferenceExpression classRef = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createReferenceExpression(qualifierClass);
|
||||
PsiReferenceExpression classRef = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createReferenceExpression(
|
||||
qualifierClass);
|
||||
final CharTable treeCharTab = SharedImplUtil.findCharTableByTree(this);
|
||||
LeafElement dot = Factory.createSingleLeafElement(JavaTokenType.DOT, ".", 0, 1, treeCharTab, manager);
|
||||
addInternal(dot, dot, SourceTreeToPsiMap.psiElementToTree(getParameterList()), Boolean.TRUE);
|
||||
@@ -122,7 +123,8 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
final String qualifiedName = qualifierClass.getQualifiedName();
|
||||
final List<PsiJavaCodeReferenceElement> refs = getImportsFromClass(importList, qualifiedName);
|
||||
if (refs.size() < JavaCodeStyleSettingsFacade.getInstance(qualifierClass.getProject()).getNamesCountToUseImportOnDemand()) {
|
||||
importList.add(JavaPsiFacade.getInstance(qualifierClass.getProject()).getElementFactory().createImportStaticStatement(qualifierClass, staticName));
|
||||
importList.add(JavaPsiFacade.getInstance(qualifierClass.getProject()).getElementFactory().createImportStaticStatement(qualifierClass,
|
||||
staticName));
|
||||
} else {
|
||||
for (PsiJavaCodeReferenceElement ref : refs) {
|
||||
final PsiImportStaticStatement importStatement = PsiTreeUtil.getParentOfType(ref, PsiImportStaticStatement.class);
|
||||
@@ -130,7 +132,8 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
importStatement.delete();
|
||||
}
|
||||
}
|
||||
importList.add(JavaPsiFacade.getInstance(qualifierClass.getProject()).getElementFactory().createImportStaticStatement(qualifierClass, "*"));
|
||||
importList.add(JavaPsiFacade.getInstance(qualifierClass.getProject()).getElementFactory().createImportStaticStatement(qualifierClass,
|
||||
"*"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,16 +177,6 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
return getQualifierExpression();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference getReference() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
return advancedResolve(false).getElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCaches() {
|
||||
myCachedQName = null;
|
||||
@@ -316,18 +309,6 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
return getCachedTextSkipWhiteSpaceAndComments();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQualifiedName() {
|
||||
return getCanonicalText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferenceName() {
|
||||
PsiElement element = getReferenceNameElement();
|
||||
if (element == null) return null;
|
||||
return element.getText();
|
||||
}
|
||||
|
||||
private final Function<PsiReferenceExpressionImpl, PsiType> ourTypeEvaluator = new TypeEvaluator();
|
||||
|
||||
private static class TypeEvaluator implements NullableFunction<PsiReferenceExpressionImpl, PsiType> {
|
||||
@@ -409,20 +390,7 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
// optimization: methodCallExpression should resolve to a method
|
||||
if (parentIsMethodCall != resolvingToMethod) return false;
|
||||
|
||||
return element.getManager().areElementsEquivalent(element, resolve());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
//this reference's variants are rather obtained with processVariants()
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
return super.isReferenceTo(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -435,7 +403,7 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
|
||||
filter.addFilter(ElementClassFilter.VARIABLE);
|
||||
|
||||
FilterScopeProcessor proc = new FilterScopeProcessor(filter, processor) {
|
||||
FilterScopeProcessor filterProcessor = new FilterScopeProcessor<CandidateInfo>(filter, processor) {
|
||||
private final Set<String> myVarNames = new THashSet<String>();
|
||||
|
||||
@Override
|
||||
@@ -454,7 +422,7 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
}
|
||||
|
||||
};
|
||||
PsiScopesUtil.resolveAndWalk(proc, this, null, true);
|
||||
PsiScopesUtil.resolveAndWalk(filterProcessor, this, null, true);
|
||||
}
|
||||
|
||||
private static boolean seemsScrambled(PsiClass element) {
|
||||
@@ -469,24 +437,11 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
Character.isLowerCase(qualifiedName.charAt(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JavaResolveResult advancedResolve(boolean incompleteCode) {
|
||||
final JavaResolveResult[] results = multiResolve(incompleteCode);
|
||||
if (results.length == 1) return results[0];
|
||||
return JavaResolveResult.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getReferenceNameElement() {
|
||||
return findChildByRoleAsPsiElement(ChildRole.REFERENCE_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReferenceParameterList getParameterList() {
|
||||
return (PsiReferenceParameterList)findChildByRoleAsPsiElement(ChildRole.REFERENCE_PARAMETER_LIST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextOffset() {
|
||||
ASTNode refName = findChildByRole(ChildRole.REFERENCE_NAME);
|
||||
@@ -684,20 +639,6 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
return new TextRange(nameChild.getStartOffsetInParent(), getTextLength());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiType[] getTypeParameters() {
|
||||
final PsiReferenceParameterList parameterList = getParameterList();
|
||||
if (parameterList == null) return PsiType.EMPTY_ARRAY;
|
||||
return parameterList.getTypeArguments();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getClassNameText() {
|
||||
String cachedQName = myCachedQName;
|
||||
@@ -744,4 +685,3 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
return whiteSpaceAndComments;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
@@ -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.
|
||||
*/
|
||||
|
||||
class C {
|
||||
interface Simplest {
|
||||
void m();
|
||||
}
|
||||
void simplest() { }
|
||||
|
||||
void test() {
|
||||
<error descr="Incompatible types. Found: 'null', required: 'C.Simplest'">Simplest simplest = this::simplest;</error>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
PsiJavaFile:MethodRef0.java
|
||||
PsiMethodReferenceExpression:a.b.C::m
|
||||
PsiReferenceExpression:a.b.C
|
||||
PsiReferenceExpression:a.b
|
||||
PsiReferenceExpression:a
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:a('a')
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:b('b')
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:C('C')
|
||||
PsiJavaToken:DOUBLE_COLON('::')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:m('m')
|
||||
@@ -0,0 +1,27 @@
|
||||
PsiJavaFile:MethodRef1.java
|
||||
PsiMethodReferenceExpression:a.b.C<T>::new
|
||||
PsiTypeElement:a.b.C<T>
|
||||
PsiJavaCodeReferenceElement:a.b.C<T>
|
||||
PsiJavaCodeReferenceElement:a.b
|
||||
PsiJavaCodeReferenceElement:a
|
||||
PsiIdentifier:a('a')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiIdentifier:b('b')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiIdentifier:C('C')
|
||||
PsiReferenceParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeElement:T
|
||||
PsiJavaCodeReferenceElement:T
|
||||
PsiIdentifier:T('T')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiJavaToken:DOUBLE_COLON('::')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiKeyword:new('new')
|
||||
@@ -0,0 +1,16 @@
|
||||
PsiJavaFile:MethodRef2.java
|
||||
PsiMethodReferenceExpression:C::<T>m
|
||||
PsiReferenceExpression:C
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:C('C')
|
||||
PsiJavaToken:DOUBLE_COLON('::')
|
||||
PsiReferenceParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeElement:T
|
||||
PsiJavaCodeReferenceElement:T
|
||||
PsiIdentifier:T('T')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiJavaToken:GT('>')
|
||||
PsiIdentifier:m('m')
|
||||
@@ -0,0 +1,17 @@
|
||||
PsiJavaFile:MethodRef3.java
|
||||
PsiMethodReferenceExpression:a[i]::m
|
||||
PsiArrayAccessExpression:a[i]
|
||||
PsiReferenceExpression:a
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:a('a')
|
||||
PsiJavaToken:LBRACKET('[')
|
||||
PsiReferenceExpression:i
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:i('i')
|
||||
PsiJavaToken:RBRACKET(']')
|
||||
PsiJavaToken:DOUBLE_COLON('::')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:m('m')
|
||||
@@ -0,0 +1,11 @@
|
||||
PsiJavaFile:MethodRef4.java
|
||||
PsiMethodReferenceExpression:int[]::clone
|
||||
PsiTypeElement:int[]
|
||||
PsiTypeElement:int
|
||||
PsiKeyword:int('int')
|
||||
PsiJavaToken:LBRACKET('[')
|
||||
PsiJavaToken:RBRACKET(']')
|
||||
PsiJavaToken:DOUBLE_COLON('::')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:clone('clone')
|
||||
@@ -0,0 +1,55 @@
|
||||
PsiJavaFile:MethodRef5.java
|
||||
PsiMethodReferenceExpression:(f ? list.map(String::length) : Collections.emptyList())::iterator
|
||||
PsiParenthesizedExpression:(f ? list.map(String::length) : Collections.emptyList())
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiConditionalExpression:f ? list.map(String::length) : Collections.emptyList()
|
||||
PsiReferenceExpression:f
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:f('f')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:QUEST('?')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethodCallExpression:list.map(String::length)
|
||||
PsiReferenceExpression:list.map
|
||||
PsiReferenceExpression:list
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:list('list')
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:map('map')
|
||||
PsiExpressionList
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiMethodReferenceExpression:String::length
|
||||
PsiReferenceExpression:String
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:String('String')
|
||||
PsiJavaToken:DOUBLE_COLON('::')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:length('length')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:COLON(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiMethodCallExpression:Collections.emptyList()
|
||||
PsiReferenceExpression:Collections.emptyList
|
||||
PsiReferenceExpression:Collections
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:Collections('Collections')
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:emptyList('emptyList')
|
||||
PsiExpressionList
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiJavaToken:DOUBLE_COLON('::')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:iterator('iterator')
|
||||
@@ -0,0 +1,11 @@
|
||||
PsiJavaFile:PrimitiveFieldAccess.java
|
||||
PsiReferenceExpression:int.x
|
||||
PsiClassObjectAccessExpression:int
|
||||
PsiTypeElement:int
|
||||
PsiKeyword:int('int')
|
||||
PsiErrorElement:.class expected
|
||||
<empty list>
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:x('x')
|
||||
+1
@@ -184,4 +184,5 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
public void testIDEA84533() throws Exception { doTest(false, false); }
|
||||
public void testClassLiteral() throws Exception { doTest(false, false); }
|
||||
public void testExtensionMethods() throws Exception { doTest(false, false); }
|
||||
public void testMethodReferences() throws Exception { doTest(false, false); }
|
||||
}
|
||||
|
||||
+8
@@ -111,9 +111,17 @@ public class ExpressionParserTest extends JavaParsingTestCase {
|
||||
public void testQualifiedSuperMethodCall1() { doParserTest("d.super(0)"); }
|
||||
public void testSuperMethodCallTypeParameterList() { doParserTest("super()"); }
|
||||
public void testPrimitiveClassObjectAccess() { doParserTest("int.class"); }
|
||||
public void testPrimitiveFieldAccess() { doParserTest("int.x"); }
|
||||
public void testChainedClassObjectAccess() { doParserTest("A.class.B.class"); }
|
||||
public void testChainedThisObjectAccess() { doParserTest("A.this.B.this"); }
|
||||
|
||||
public void testMethodRef0() { doParserTest("a.b.C::m"); }
|
||||
public void testMethodRef1() { doParserTest("a.b.C<T>::new"); }
|
||||
public void testMethodRef2() { doParserTest("C::<T>m"); }
|
||||
public void testMethodRef3() { doParserTest("a[i]::m"); }
|
||||
public void testMethodRef4() { doParserTest("int[]::clone"); }
|
||||
public void testMethodRef5() { doParserTest("(f ? list.map(String::length) : Collections.emptyList())::iterator"); }
|
||||
|
||||
private void doParserTest(@NonNls final String text) {
|
||||
doParserTest(text, new MyTestParser());
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ import java.util.List;
|
||||
|
||||
public class BookmarksAction extends AnAction implements DumbAware, MasterDetailPopupBuilder.Delegate {
|
||||
|
||||
private JBPopup myPopup;
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
DataContext dataContext = e.getDataContext();
|
||||
@@ -59,6 +61,7 @@ public class BookmarksAction extends AnAction implements DumbAware, MasterDetail
|
||||
final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
|
||||
if (project == null) return;
|
||||
|
||||
if (myPopup != null && myPopup.isVisible()) return;
|
||||
|
||||
final DefaultListModel model = buildModel(project);
|
||||
|
||||
@@ -72,13 +75,13 @@ public class BookmarksAction extends AnAction implements DumbAware, MasterDetail
|
||||
actions.add(new MoveBookmarkUpAction(project, list));
|
||||
actions.add(new MoveBookmarkDownAction(project, list));
|
||||
|
||||
final JBPopup popup = new MasterDetailPopupBuilder(project).
|
||||
myPopup = new MasterDetailPopupBuilder(project).
|
||||
setActionsGroup(actions).
|
||||
setList(list).
|
||||
setDelegate(this).createMasterDetailPopup();
|
||||
|
||||
editDescriptionAction.setPopup(popup);
|
||||
popup.showCenteredInCurrentWindow(project);
|
||||
editDescriptionAction.setPopup(myPopup);
|
||||
myPopup.showCenteredInCurrentWindow(project);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -126,7 +126,7 @@ public class OpenFileDescriptor implements Navigatable {
|
||||
FileType type = FileTypeManager.getInstance().getKnownFileTypeOrAssociate(myFile,project);
|
||||
if (type == null || !myFile.isValid()) return false;
|
||||
|
||||
if (type instanceof INativeFileType && requestFocus) {
|
||||
if (type instanceof INativeFileType) {
|
||||
return ((INativeFileType) type).openFileInAssociatedApplication(project, myFile);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.actionSystem.ToggleAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.fileTypes.INativeFileType;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.vfs.PersistentFSConstants;
|
||||
@@ -179,7 +180,7 @@ public abstract class AutoScrollToSourceHandler {
|
||||
if (vFile != null) {
|
||||
// Attempt to navigate to the virtual file with unknown file type will show a modal dialog
|
||||
// asking to register some file type for this file. This behaviour is undesirable when autoscrolling.
|
||||
if (vFile.getFileType() == FileTypes.UNKNOWN) return;
|
||||
if (vFile.getFileType() == FileTypes.UNKNOWN || vFile.getFileType() instanceof INativeFileType) return;
|
||||
|
||||
//IDEA-84881 Don't autoscroll to very large files
|
||||
if (vFile.getLength() > PersistentFSConstants.getMaxIntellisenseFileSize()) return;
|
||||
|
||||
@@ -4,14 +4,10 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.HierarchyEvent;
|
||||
import java.awt.event.HierarchyListener;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author evgeny.zakrevsky
|
||||
|
||||
@@ -91,7 +91,20 @@ public class AsyncProcessIcon extends AnimatedIcon {
|
||||
}
|
||||
|
||||
public static class Big extends AsyncProcessIcon {
|
||||
private static final Icon[] BIG_ICONS = findIcons("/process/big/step_", null);
|
||||
private static final Icon[] BIG_ICONS = {
|
||||
AllIcons.Process.Big.Step_1,
|
||||
AllIcons.Process.Big.Step_2,
|
||||
AllIcons.Process.Big.Step_3,
|
||||
AllIcons.Process.Big.Step_4,
|
||||
AllIcons.Process.Big.Step_5,
|
||||
AllIcons.Process.Big.Step_6,
|
||||
AllIcons.Process.Big.Step_7,
|
||||
AllIcons.Process.Big.Step_8,
|
||||
AllIcons.Process.Big.Step_9,
|
||||
AllIcons.Process.Big.Step_10,
|
||||
AllIcons.Process.Big.Step_11,
|
||||
AllIcons.Process.Big.Step_12
|
||||
};
|
||||
private static final Icon BIG_PASSIVE_ICON = AllIcons.Process.Big.Step_passive;
|
||||
|
||||
public Big(@NonNls final String name) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.intellij.util.ui;
|
||||
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.icons.AllIcons;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -24,16 +24,26 @@ import java.awt.*;
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class RefreshFileSystemIcon extends AnimatedIcon {
|
||||
private static final Icon[] ICONS = getIcons("/process/fs/step_", 18);
|
||||
|
||||
private static Icon[] getIcons(String path, int count) {
|
||||
Icon[] icons = new Icon[count];
|
||||
for (int i = 0; i < icons.length; i++) {
|
||||
int index = i + 1;
|
||||
icons[i] = IconLoader.getIcon(path + index + ".png");
|
||||
}
|
||||
return icons;
|
||||
}
|
||||
private static final Icon[] ICONS = {
|
||||
AllIcons.Process.FS.Step_1,
|
||||
AllIcons.Process.FS.Step_2,
|
||||
AllIcons.Process.FS.Step_3,
|
||||
AllIcons.Process.FS.Step_4,
|
||||
AllIcons.Process.FS.Step_5,
|
||||
AllIcons.Process.FS.Step_6,
|
||||
AllIcons.Process.FS.Step_7,
|
||||
AllIcons.Process.FS.Step_8,
|
||||
AllIcons.Process.FS.Step_9,
|
||||
AllIcons.Process.FS.Step_10,
|
||||
AllIcons.Process.FS.Step_11,
|
||||
AllIcons.Process.FS.Step_12,
|
||||
AllIcons.Process.FS.Step_13,
|
||||
AllIcons.Process.FS.Step_14,
|
||||
AllIcons.Process.FS.Step_15,
|
||||
AllIcons.Process.FS.Step_16,
|
||||
AllIcons.Process.FS.Step_17,
|
||||
AllIcons.Process.FS.Step_18
|
||||
};
|
||||
|
||||
public RefreshFileSystemIcon() {
|
||||
super("Refreshing filesystem", ICONS, EmptyIcon.ICON_16, 800);
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
package com.intellij.util.io;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import sun.misc.Cleaner;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
public abstract class DirectBufferWrapper extends ByteBufferWrapper {
|
||||
protected static final Logger LOG = Logger.getInstance("#com.intellij.util.io.DirectBufferWrapper");
|
||||
@@ -49,6 +54,24 @@ public abstract class DirectBufferWrapper extends ByteBufferWrapper {
|
||||
@Override
|
||||
public void unmap() {
|
||||
if (isDirty()) flush();
|
||||
if (myBuffer != null) disposeDirectBuffer((DirectBuffer)myBuffer);
|
||||
myBuffer = null;
|
||||
}
|
||||
|
||||
static boolean disposeDirectBuffer(final DirectBuffer buffer) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
@Nullable
|
||||
public Object run() {
|
||||
try {
|
||||
Cleaner cleaner = buffer.cleaner();
|
||||
if (cleaner != null) cleaner.clean(); // Already cleaned otherwise
|
||||
return null;
|
||||
}
|
||||
catch (Exception e) {
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}) == null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,16 +16,12 @@
|
||||
package com.intellij.util.io;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import sun.misc.Cleaner;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
@@ -81,19 +77,7 @@ public abstract class MappedBufferWrapper extends ByteBufferWrapper {
|
||||
return false;
|
||||
}
|
||||
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
@Nullable
|
||||
public Object run() {
|
||||
try {
|
||||
Cleaner cleaner = ((DirectBuffer)buffer).cleaner();
|
||||
if (cleaner != null) cleaner.clean(); // Already cleaned otherwise
|
||||
return null;
|
||||
}
|
||||
catch (Exception e) {
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
}) == null;
|
||||
return DirectBufferWrapper.disposeDirectBuffer((DirectBuffer)buffer);
|
||||
}
|
||||
|
||||
private static boolean tryForce(MappedByteBuffer buffer) {
|
||||
|
||||
@@ -370,7 +370,7 @@
|
||||
<categoryKey>intention.category.strings</categoryKey>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.siyeh.ipp.concatenation.MakeAppendChainIntoAppendSequenceIntention</className>
|
||||
<className>com.siyeh.ipp.concatenation.MakeCallChainIntoCallSequenceIntention</className>
|
||||
<categoryKey>intention.category.other</categoryKey>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
|
||||
@@ -81,8 +81,8 @@ replace.if.with.conditional.intention.name=Replace 'if else' with '?:'
|
||||
replace.if.with.conditional.intention.family.name=Replace If Else with Conditional
|
||||
replace.equality.with.equals.intention.name=Replace '==' with '.equals()'
|
||||
replace.equality.with.equals.intention.family.name=Replace Equality with Equals
|
||||
make.append.chain.into.append.sequence.intention.name=Make '.append()' chain into '.append()' sequence
|
||||
make.append.chain.into.append.sequence.intention.family.name=Make Append Chain Into Append Sequence
|
||||
make.call.chain.into.call.sequence.intention.name=Make method call chain into method call sequence
|
||||
make.call.chain.into.call.sequence.intention.family.name=Make Call Chain Into Call Sequence
|
||||
detail.exceptions.intention.name=Detail exceptions
|
||||
detail.exceptions.intention.family.name=Detail Exceptions
|
||||
flip.conditional.intention.name=Flip '?:'
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.siyeh.ipp.concatenation;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
|
||||
class AppendChainPredicate implements PsiElementPredicate {
|
||||
|
||||
public boolean satisfiedBy(PsiElement element) {
|
||||
if (!AppendUtil.isAppendCall(element)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethodCallExpression call = (PsiMethodCallExpression)element;
|
||||
final PsiReferenceExpression methodExpression =
|
||||
call.getMethodExpression();
|
||||
final PsiExpression qualifier =
|
||||
methodExpression.getQualifierExpression();
|
||||
if (!(qualifier instanceof PsiMethodCallExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethodCallExpression qualifierCall =
|
||||
(PsiMethodCallExpression)element;
|
||||
if (!AppendUtil.isAppendCall(qualifierCall)) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiExpressionStatement) {
|
||||
return true;
|
||||
}
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (parent instanceof PsiLocalVariable &&
|
||||
grandParent instanceof PsiDeclarationStatement) {
|
||||
final PsiDeclarationStatement declarationStatement =
|
||||
(PsiDeclarationStatement)grandParent;
|
||||
if (declarationStatement.getDeclaredElements().length == 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return parent instanceof PsiAssignmentExpression &&
|
||||
grandParent instanceof PsiExpressionStatement;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.siyeh.ipp.concatenation;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
class AppendUtil {
|
||||
|
||||
private AppendUtil() {
|
||||
}
|
||||
|
||||
public static boolean isAppendCall(PsiElement element) {
|
||||
if (!(element instanceof PsiMethodCallExpression)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethodCallExpression methodCallExpression =
|
||||
(PsiMethodCallExpression)element;
|
||||
final PsiReferenceExpression methodExpression =
|
||||
methodCallExpression.getMethodExpression();
|
||||
@NonNls final String callName = methodExpression.getReferenceName();
|
||||
if (!"append".equals(callName)) {
|
||||
return false;
|
||||
}
|
||||
final PsiMethod method = methodCallExpression.resolveMethod();
|
||||
final PsiClass containingClass;
|
||||
if (method == null) {
|
||||
// if the argument has no type because of invalid code
|
||||
// this uses the qualifier as type, so the conversion too
|
||||
// append sequence is still applicable
|
||||
final PsiExpression qualifierExpression =
|
||||
methodExpression.getQualifierExpression();
|
||||
if (qualifierExpression == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiType type = qualifierExpression.getType();
|
||||
if (!(type instanceof PsiClassType)) {
|
||||
return false;
|
||||
}
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
containingClass = classType.resolve();
|
||||
}
|
||||
else {
|
||||
containingClass = method.getContainingClass();
|
||||
}
|
||||
if (containingClass == null) {
|
||||
return false;
|
||||
}
|
||||
final String name = containingClass.getQualifiedName();
|
||||
if (CommonClassNames.JAVA_LANG_STRING_BUFFER.equals(name) ||
|
||||
CommonClassNames.JAVA_LANG_STRING_BUILDER.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
final Project project = containingClass.getProject();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
final PsiClass appendableClass =
|
||||
psiFacade.findClass("java.lang.Appendable",
|
||||
GlobalSearchScope.allScope(project));
|
||||
if (appendableClass == null) {
|
||||
return false;
|
||||
}
|
||||
return containingClass.isInheritor(appendableClass, true);
|
||||
}
|
||||
}
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.siyeh.ipp.concatenation;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class MakeAppendChainIntoAppendSequenceIntention extends Intention {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected PsiElementPredicate getElementPredicate() {
|
||||
return new AppendChainPredicate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processIntention(PsiElement element)
|
||||
throws IncorrectOperationException {
|
||||
final PsiExpression call = (PsiExpression)element;
|
||||
final List<String> argumentsList = new ArrayList<String>();
|
||||
PsiExpression currentCall = call;
|
||||
while (AppendUtil.isAppendCall(currentCall)) {
|
||||
final PsiMethodCallExpression methodCallExpression =
|
||||
(PsiMethodCallExpression)currentCall;
|
||||
final PsiExpressionList arguments =
|
||||
methodCallExpression.getArgumentList();
|
||||
final String argumentsText = arguments.getText();
|
||||
argumentsList.add(argumentsText);
|
||||
final PsiReferenceExpression methodExpression =
|
||||
methodCallExpression.getMethodExpression();
|
||||
currentCall = methodExpression.getQualifierExpression();
|
||||
if (currentCall == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
final String targetText;
|
||||
final PsiStatement appendStatement;
|
||||
@NonNls final String firstStatement;
|
||||
final PsiElement parent = call.getParent();
|
||||
if (parent instanceof PsiExpressionStatement) {
|
||||
targetText = currentCall.getText();
|
||||
appendStatement = (PsiStatement)parent;
|
||||
firstStatement = null;
|
||||
}
|
||||
else {
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
appendStatement = (PsiStatement)grandParent;
|
||||
if (parent instanceof PsiAssignmentExpression &&
|
||||
grandParent instanceof PsiExpressionStatement) {
|
||||
final PsiAssignmentExpression assignment =
|
||||
(PsiAssignmentExpression)parent;
|
||||
final PsiExpression lhs = assignment.getLExpression();
|
||||
targetText = lhs.getText();
|
||||
final PsiJavaToken token = assignment.getOperationSign();
|
||||
firstStatement = targetText + token.getText() +
|
||||
currentCall.getText() + ';';
|
||||
}
|
||||
else {
|
||||
final PsiDeclarationStatement declaration =
|
||||
(PsiDeclarationStatement)appendStatement;
|
||||
final PsiVariable variable =
|
||||
(PsiVariable)declaration.getDeclaredElements()[0];
|
||||
targetText = variable.getName();
|
||||
final PsiType variableType = variable.getType();
|
||||
if (variable.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
firstStatement =
|
||||
"final " + variableType.getPresentableText() +
|
||||
' ' + variable.getName() + '=' +
|
||||
currentCall.getText() + ';';
|
||||
}
|
||||
else {
|
||||
firstStatement = variableType.getPresentableText() +
|
||||
' ' + variable.getName() + '=' +
|
||||
currentCall.getText() + ';';
|
||||
}
|
||||
}
|
||||
}
|
||||
final StringBuilder builder = new StringBuilder("{");
|
||||
if (firstStatement != null) {
|
||||
builder.append(firstStatement);
|
||||
}
|
||||
Collections.reverse(argumentsList);
|
||||
for (String argument : argumentsList) {
|
||||
builder.append(targetText);
|
||||
builder.append(".append");
|
||||
builder.append(argument);
|
||||
builder.append(';');
|
||||
}
|
||||
builder.append('}');
|
||||
final PsiManager manager = element.getManager();
|
||||
final Project project = manager.getProject();
|
||||
final PsiElementFactory factory =
|
||||
JavaPsiFacade.getElementFactory(project);
|
||||
final PsiElement appendStatementParent = appendStatement.getParent();
|
||||
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject());
|
||||
final PsiCodeBlock codeBlock =
|
||||
factory.createCodeBlockFromText(builder.toString(),
|
||||
appendStatement);
|
||||
if (appendStatementParent instanceof PsiLoopStatement ||
|
||||
appendStatementParent instanceof PsiIfStatement) {
|
||||
final PsiElement insertedStatement =
|
||||
appendStatement.replace(codeBlock);
|
||||
codeStyleManager.reformat(insertedStatement);
|
||||
}
|
||||
else {
|
||||
final PsiStatement[] statements = codeBlock.getStatements();
|
||||
for (PsiStatement statement : statements) {
|
||||
final PsiElement insertedStatement =
|
||||
appendStatementParent.addBefore(statement,
|
||||
appendStatement);
|
||||
codeStyleManager.reformat(insertedStatement);
|
||||
}
|
||||
appendStatement.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.siyeh.ipp.concatenation;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import com.siyeh.ipp.psiutils.HighlightUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class MakeCallChainIntoCallSequenceIntention extends Intention {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected PsiElementPredicate getElementPredicate() {
|
||||
return new MethodCallChainPredicate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
final List<String> callTexts = new ArrayList<String>();
|
||||
PsiExpression root = (PsiExpression)element;
|
||||
while (root instanceof PsiMethodCallExpression) {
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) root;
|
||||
final PsiExpressionList arguments = methodCallExpression.getArgumentList();
|
||||
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
|
||||
callTexts.add(methodExpression.getReferenceName() + arguments.getText());
|
||||
root = methodExpression.getQualifierExpression();
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
final PsiType rootType = root.getType();
|
||||
if (rootType == null) {
|
||||
return;
|
||||
}
|
||||
final String targetText;
|
||||
final PsiStatement appendStatement;
|
||||
@NonNls final String firstStatement;
|
||||
final String variableDeclaration;
|
||||
final boolean showRenameTemplate;
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiExpressionStatement) {
|
||||
targetText = root.getText();
|
||||
appendStatement = (PsiStatement)parent;
|
||||
firstStatement = null;
|
||||
variableDeclaration = null;
|
||||
showRenameTemplate = false;
|
||||
}
|
||||
else {
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
appendStatement = (PsiStatement)grandParent;
|
||||
if (parent instanceof PsiAssignmentExpression && grandParent instanceof PsiExpressionStatement) {
|
||||
final PsiAssignmentExpression assignment = (PsiAssignmentExpression)parent;
|
||||
final PsiExpression lhs = assignment.getLExpression();
|
||||
if (!(lhs instanceof PsiReferenceExpression)) {
|
||||
return;
|
||||
}
|
||||
final PsiReferenceExpression expression = (PsiReferenceExpression)lhs;
|
||||
final PsiElement target = expression.resolve();
|
||||
if (!(target instanceof PsiVariable)) {
|
||||
return;
|
||||
}
|
||||
final PsiVariable variable = (PsiVariable)target;
|
||||
final PsiType variableType = variable.getType();
|
||||
if (variableType.equals(rootType)) {
|
||||
targetText = lhs.getText();
|
||||
final PsiJavaToken token = assignment.getOperationSign();
|
||||
firstStatement = targetText + token.getText() + root.getText() + ';';
|
||||
showRenameTemplate = false;
|
||||
} else {
|
||||
targetText = "x";
|
||||
showRenameTemplate = true;
|
||||
final Project project = element.getProject();
|
||||
final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
|
||||
if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
|
||||
firstStatement = "final " + rootType.getCanonicalText() + ' ' + targetText + '=' + root.getText() + ';';
|
||||
} else {
|
||||
firstStatement = rootType.getCanonicalText() + ' ' + targetText + '=' + root.getText() + ';';
|
||||
}
|
||||
}
|
||||
variableDeclaration = null;
|
||||
}
|
||||
else {
|
||||
final PsiDeclarationStatement declaration = (PsiDeclarationStatement)appendStatement;
|
||||
final PsiVariable variable = (PsiVariable)declaration.getDeclaredElements()[0];
|
||||
final PsiType variableType = variable.getType();
|
||||
if (variableType.equals(rootType)) {
|
||||
targetText = variable.getName();
|
||||
if (variable.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
firstStatement = "final " + variableType.getCanonicalText() + ' ' + variable.getName() + '=' + root.getText() + ';';
|
||||
}
|
||||
else {
|
||||
firstStatement = variableType.getCanonicalText() + ' ' + variable.getName() + '=' + root.getText() + ';';
|
||||
}
|
||||
variableDeclaration = null;
|
||||
showRenameTemplate = false;
|
||||
} else {
|
||||
if (variable.hasModifierProperty(PsiModifier.FINAL)) {
|
||||
variableDeclaration = "final " + variableType.getCanonicalText() + ' ' + variable.getName() + '=';
|
||||
}
|
||||
else {
|
||||
variableDeclaration = variableType.getCanonicalText() + ' ' + variable.getName() + '=';
|
||||
}
|
||||
targetText = "x";
|
||||
showRenameTemplate = true;
|
||||
final Project project = element.getProject();
|
||||
final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(project);
|
||||
if (codeStyleSettings.GENERATE_FINAL_LOCALS) {
|
||||
firstStatement = "final " + rootType.getCanonicalText() + " x=" + root.getText() + ';';
|
||||
} else {
|
||||
firstStatement = rootType.getCanonicalText() + " x=" + root.getText() + ';';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final StringBuilder builder = new StringBuilder("{\n");
|
||||
if (firstStatement != null) {
|
||||
builder.append(firstStatement);
|
||||
}
|
||||
Collections.reverse(callTexts);
|
||||
for (int i = 0, size = callTexts.size(); i < size; i++) {
|
||||
final String callText = callTexts.get(i);
|
||||
if (i == size - 1 && variableDeclaration != null) {
|
||||
builder.append(variableDeclaration);
|
||||
}
|
||||
builder.append(targetText).append('.').append(callText).append(";\n");
|
||||
}
|
||||
builder.append('}');
|
||||
final PsiManager manager = element.getManager();
|
||||
final Project project = manager.getProject();
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiElement appendStatementParent = appendStatement.getParent();
|
||||
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject());
|
||||
final PsiCodeBlock codeBlock = factory.createCodeBlockFromText(builder.toString(), appendStatement);
|
||||
if (appendStatementParent instanceof PsiLoopStatement || appendStatementParent instanceof PsiIfStatement) {
|
||||
final PsiElement insertedCodeBlock = appendStatement.replace(codeBlock);
|
||||
final PsiCodeBlock reformattedCodeBlock = (PsiCodeBlock)codeStyleManager.reformat(insertedCodeBlock);
|
||||
if (showRenameTemplate) {
|
||||
final PsiStatement[] statements = reformattedCodeBlock.getStatements();
|
||||
final PsiVariable variable = (PsiVariable)((PsiDeclarationStatement) statements[0]).getDeclaredElements()[0];
|
||||
HighlightUtil.showRenameTemplate(appendStatementParent, variable);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiStatement[] statements = codeBlock.getStatements();
|
||||
PsiVariable variable = null;
|
||||
for (int i = 0, length = statements.length; i < length; i++) {
|
||||
final PsiElement insertedStatement = appendStatementParent.addBefore(statements[i], appendStatement);
|
||||
if (i == 0 && showRenameTemplate) {
|
||||
variable = (PsiVariable)((PsiDeclarationStatement) insertedStatement).getDeclaredElements()[0];
|
||||
}
|
||||
codeStyleManager.reformat(insertedStatement);
|
||||
}
|
||||
appendStatement.delete();
|
||||
if (variable != null) {
|
||||
HighlightUtil.showRenameTemplate(appendStatementParent, variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.siyeh.ipp.concatenation;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class MethodCallChainPredicate implements PsiElementPredicate {
|
||||
|
||||
public boolean satisfiedBy(PsiElement element) {
|
||||
if (!isCallChain(element)) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiExpressionStatement) {
|
||||
return true;
|
||||
}
|
||||
else if (parent instanceof PsiLocalVariable) {
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (!(grandParent instanceof PsiDeclarationStatement)) {
|
||||
return false;
|
||||
}
|
||||
final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)grandParent;
|
||||
return declarationStatement.getDeclaredElements().length == 1;
|
||||
}
|
||||
else if (parent instanceof PsiAssignmentExpression) {
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
return grandParent instanceof PsiExpressionStatement;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isCallChain(PsiElement element) {
|
||||
PsiClass aClass1 = getQualifierExpressionType(element);
|
||||
if (aClass1 == null) {
|
||||
return false;
|
||||
}
|
||||
boolean first = true;
|
||||
while (aClass1 != null) {
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element;
|
||||
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
|
||||
final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
|
||||
PsiClass aClass2 = getQualifierExpressionType(qualifierExpression);
|
||||
if (!first) {
|
||||
if (aClass2 == null) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
if (!aClass1.equals(aClass2)) {
|
||||
return false;
|
||||
}
|
||||
aClass1 = aClass2;
|
||||
element = qualifierExpression;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getQualifierExpressionType(PsiElement element) {
|
||||
if (!(element instanceof PsiMethodCallExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element;
|
||||
final PsiMethod method = methodCallExpression.resolveMethod();
|
||||
if (method != null) {
|
||||
return method.getContainingClass();
|
||||
}
|
||||
final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression();
|
||||
final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
|
||||
if (!(qualifierExpression instanceof PsiMethodCallExpression)) {
|
||||
return null;
|
||||
}
|
||||
final PsiType type = qualifierExpression.getType();
|
||||
if (!(type instanceof PsiClassType)) {
|
||||
return null;
|
||||
}
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
return classType.resolve();
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,14 @@
|
||||
*/
|
||||
package com.siyeh.ipp.psiutils;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.template.Expression;
|
||||
import com.intellij.codeInsight.template.Template;
|
||||
import com.intellij.codeInsight.template.TemplateBuilderImpl;
|
||||
import com.intellij.codeInsight.template.TemplateManager;
|
||||
import com.intellij.codeInsight.template.impl.MacroCallNode;
|
||||
import com.intellij.codeInsight.template.macro.SuggestVariableNameMacro;
|
||||
import com.intellij.find.FindManager;
|
||||
import com.intellij.find.FindModel;
|
||||
import com.intellij.openapi.application.Application;
|
||||
@@ -27,11 +34,16 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.wm.StatusBar;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.Query;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -118,4 +130,32 @@ public class HighlightUtil {
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static void showRenameTemplate(PsiElement context, PsiNameIdentifierOwner element) {
|
||||
context = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(context);
|
||||
final Query<PsiReference> query = ReferencesSearch.search(element, element.getUseScope());
|
||||
final Collection<PsiReference> references = query.findAll();
|
||||
final Project project = context.getProject();
|
||||
final FileEditorManager fileEditorManager =
|
||||
FileEditorManager.getInstance(project);
|
||||
final Editor editor = fileEditorManager.getSelectedTextEditor();
|
||||
if (editor == null) {
|
||||
return;
|
||||
}
|
||||
final TemplateBuilderImpl builder = new TemplateBuilderImpl(context);
|
||||
final Expression macroCallNode = new MacroCallNode(
|
||||
new SuggestVariableNameMacro());
|
||||
final PsiElement identifier = element.getNameIdentifier();
|
||||
builder.replaceElement(identifier, "PATTERN", macroCallNode, true);
|
||||
for (PsiReference reference : references) {
|
||||
builder.replaceElement(reference, "PATTERN", "PATTERN", false);
|
||||
}
|
||||
final Template template = builder.buildInlineTemplate();
|
||||
final TextRange textRange = context.getTextRange();
|
||||
final int startOffset = textRange.getStartOffset();
|
||||
editor.getCaretModel().moveToOffset(startOffset);
|
||||
final TemplateManager templateManager =
|
||||
TemplateManager.getInstance(project);
|
||||
templateManager.startTemplate(editor, template);
|
||||
}
|
||||
}
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention replaces chains of <b>StringBuffer.append()</b> calls with
|
||||
the equivalent sequence of call statements.
|
||||
</body>
|
||||
</html>
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention replaces chains of method calls with the equivalent sequence of call statements.
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user