summaryrefslogtreecommitdiff
path: root/java/java-psi-impl/src/com
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2013-04-01 14:41:51 -0700
committerJean-Baptiste Queru <jbq@google.com>2013-04-01 14:41:51 -0700
commit2bd2b7c2623d4266384e890271869efc044aabff (patch)
tree0b31f50e55975b6354ed458314e17b4441bb4e17 /java/java-psi-impl/src/com
parent1d526b16d476792ca7ce47616d55833115e8d6ab (diff)
downloadidea-2bd2b7c2623d4266384e890271869efc044aabff.tar.gz
Snapshot ee98b298267d0e09d2cd2f0731b6480a56dd48e7 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I4515f72af131fdea9fc6905a4dc0fe9532409a81
Diffstat (limited to 'java/java-psi-impl/src/com')
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java44
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java24
-rw-r--r--java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java22
-rw-r--r--java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java94
-rw-r--r--java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java14
-rw-r--r--java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java6
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java21
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java9
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java16
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java199
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java6
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java12
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java164
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java9
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java31
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassReferenceListElementType.java8
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaFieldStubElementType.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java25
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaParameterElementType.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/SourceStubPsiFactory.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiAnnotationStubImpl.java25
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiFieldStubImpl.java33
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java33
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/light/LightMethod.java12
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java4
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java40
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java30
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java124
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java34
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReferenceListImpl.java42
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java18
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java2
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java3
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java59
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java163
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java9
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java25
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java72
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java80
-rw-r--r--java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java1
41 files changed, 756 insertions, 771 deletions
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
index 4d96915af333..4b244364416f 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
@@ -298,28 +298,9 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
MostlySingularMultiMap<String, AnnotationData> fileData = getDataFromFile(file);
- Collection<AnnotationData> data = (Collection<AnnotationData>)fileData.get(externalName);
- for (AnnotationData ad : data) {
- if (result.contains(ad)) {
- // there can be compatible annotations in different files
- if (Comparing.equal(ad.virtualFile, file.getVirtualFile())) {
- LOG.error("Duplicate signature:\n" + externalName + "; in " + file);
- }
- }
- else {
- result.add(ad);
- }
- }
+ addAnnotations(result, externalName, file, fileData);
if (oldExternalName != null && !externalName.equals(oldExternalName)) {
- Collection<AnnotationData> oldCollection = (Collection<AnnotationData>)fileData.get(oldExternalName);
- for (AnnotationData ad : oldCollection) {
- if (result.contains(ad)) {
- LOG.error("Duplicate signature o:\n" + oldExternalName + "; in " + toVirtualFiles(files));
- }
- else {
- result.add(ad);
- }
- }
+ addAnnotations(result, oldExternalName, file, fileData);
}
}
if (result.isEmpty()) {
@@ -329,13 +310,22 @@ public abstract class BaseExternalAnnotationsManager extends ExternalAnnotations
return result;
}
- static List<VirtualFile> toVirtualFiles(List<PsiFile> files) {
- return ContainerUtil.map(files, new Function<PsiFile, VirtualFile>() {
- @Override
- public VirtualFile fun(PsiFile file) {
- return file.getVirtualFile();
+ private static void addAnnotations(@NotNull List<AnnotationData> result,
+ @NotNull String externalName,
+ @NotNull PsiFile file,
+ @NotNull MostlySingularMultiMap<String, AnnotationData> fileData) {
+ Iterable<AnnotationData> data = fileData.get(externalName);
+ for (AnnotationData ad : data) {
+ if (result.contains(ad)) {
+ // there can be compatible annotations in different files
+ if (Comparing.equal(ad.virtualFile, file.getVirtualFile())) {
+ LOG.error("Duplicate signature: '" + externalName + "'; in " + file.getVirtualFile());
+ }
}
- });
+ else {
+ result.add(ad);
+ }
+ }
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
index f78ee83b570a..1aa0ac222946 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.NullableFunction;
+import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
@@ -421,21 +422,20 @@ public class ExceptionUtil {
}
@NotNull
- public static List<PsiClassType> getUnhandledExceptions(final PsiThrowStatement throwStatement, @Nullable final PsiElement topElement) {
- final PsiExpression exception = throwStatement.getException();
- final List<PsiType> types = getPreciseThrowTypes(exception);
- return ContainerUtil.mapNotNull(types, new NullableFunction<PsiType, PsiClassType>() {
- @Override
- public PsiClassType fun(PsiType type) {
- if (type instanceof PsiClassType) {
- final PsiClassType classType = (PsiClassType)type;
+ public static List<PsiClassType> getUnhandledExceptions(PsiThrowStatement throwStatement, @Nullable PsiElement topElement) {
+ List<PsiClassType> unhandled = new SmartList<PsiClassType>();
+ for (PsiType type : getPreciseThrowTypes(throwStatement.getException())) {
+ List<PsiType> types = type instanceof PsiDisjunctionType ? ((PsiDisjunctionType)type).getDisjunctions() : Collections.singletonList(type);
+ for (PsiType subType : types) {
+ if (subType instanceof PsiClassType) {
+ PsiClassType classType = (PsiClassType)subType;
if (!isUncheckedException(classType) && !isHandled(throwStatement, classType, topElement)) {
- return classType;
+ unhandled.add(classType);
}
}
- return null;
}
- });
+ }
+ return unhandled;
}
@NotNull
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java
index 35e24fa88bd2..52e9ab691092 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java
@@ -4,6 +4,7 @@ import com.intellij.codeInsight.MemberImplementorExplorer;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.util.MethodSignature;
@@ -63,9 +64,9 @@ public class OverrideImplementExploreUtil {
}
Map<MethodSignature, PsiMethod> map = hisClass.isInterface() || method.hasModifierProperty(PsiModifier.ABSTRACT) ? abstracts : concretes;
- PsiMethod other = map.get(signature);
- if (other == null || preferLeftForImplement(method, other)) {
- map.put(signature, method);
+ fillMap(signature, method, map);
+ if (isDefaultMethod(aClass, method)) {
+ fillMap(signature, method, concretes);
}
}
@@ -92,6 +93,18 @@ public class OverrideImplementExploreUtil {
return result;
}
+ private static boolean isDefaultMethod(PsiClass aClass, PsiMethod method) {
+ return method.hasModifierProperty(PsiModifier.DEFAULT) &&
+ PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8);
+ }
+
+ private static void fillMap(HierarchicalMethodSignature signature, PsiMethod method, Map<MethodSignature, PsiMethod> map) {
+ final PsiMethod other = map.get(signature);
+ if (other == null || preferLeftForImplement(method, other)) {
+ map.put(signature, method);
+ }
+ }
+
public static void collectMethodsToImplement(PsiClass aClass,
Map<MethodSignature, PsiMethod> abstracts,
Map<MethodSignature, PsiMethod> finals,
@@ -103,7 +116,8 @@ public class OverrideImplementExploreUtil {
PsiMethod concrete = concretes.get(signature);
if (concrete == null
|| PsiUtil.getAccessLevel(concrete.getModifierList()) < PsiUtil.getAccessLevel(abstractOne.getModifierList())
- || !abstractOne.getContainingClass().isInterface() && abstractOne.getContainingClass().isInheritor(concrete.getContainingClass(), true)) {
+ || !abstractOne.getContainingClass().isInterface() && abstractOne.getContainingClass().isInheritor(concrete.getContainingClass(), true)
+ || isDefaultMethod(aClass, abstractOne)) {
if (finals.get(signature) == null) {
PsiSubstitutor subst = correctSubstitutor(abstractOne, signature.getSubstitutor());
CandidateInfo info = new CandidateInfo(abstractOne, subst);
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java
index 8722c92feb8e..54e23dd156b3 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -402,29 +402,26 @@ public class DeclarationParser {
return Pair.create(modList, isEmpty);
}
- private PsiBuilder.Marker parseMethodFromLeftParenth(final PsiBuilder builder, final PsiBuilder.Marker declaration,
- final boolean anno, final boolean constructor) {
+ private PsiBuilder.Marker parseMethodFromLeftParenth(PsiBuilder builder, PsiBuilder.Marker declaration, boolean anno, boolean constructor) {
parseParameterList(builder);
- eatBrackets(builder, constructor, "expected.semicolon");
+ eatBrackets(builder, constructor ? "expected.semicolon" : null);
myParser.getReferenceParser().parseReferenceList(builder, JavaTokenType.THROWS_KEYWORD, JavaElementType.THROWS_LIST, JavaTokenType.COMMA);
- final boolean hasDefault = expect(builder, JavaTokenType.DEFAULT_KEYWORD);
- if (hasDefault && anno) {
+ if (anno && expect(builder, JavaTokenType.DEFAULT_KEYWORD)) {
parseAnnotationValue(builder);
}
- final IElementType tokenType = builder.getTokenType();
- final boolean hasError = tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE;
- if (hasError) {
- final PsiBuilder.Marker error = builder.mark();
+ IElementType tokenType = builder.getTokenType();
+ if (tokenType != JavaTokenType.SEMICOLON && tokenType != JavaTokenType.LBRACE) {
+ PsiBuilder.Marker error = builder.mark();
// heuristic: going to next line obviously means method signature is over, starting new method (actually, another one completion hack)
- final CharSequence text = builder.getOriginalText();
+ CharSequence text = builder.getOriginalText();
Loop:
while (true) {
for (int i = builder.getCurrentOffset() - 1; i >= 0; i--) {
- final char ch = text.charAt(i);
+ char ch = text.charAt(i);
if (ch == '\n') break Loop;
else if (ch != ' ' && ch != '\t') break;
}
@@ -433,11 +430,10 @@ public class DeclarationParser {
error.error(JavaErrorMessages.message("expected.lbrace.or.semicolon"));
}
- if (hasDefault && !anno && !hasError && builder.getTokenType() != JavaTokenType.LBRACE) {
- error(builder, JavaErrorMessages.message("expected.lbrace"));
- }
- if (!expect(builder, JavaTokenType.SEMICOLON) && builder.getTokenType() == JavaTokenType.LBRACE) {
- myParser.getStatementParser().parseCodeBlock(builder);
+ if (!expect(builder, JavaTokenType.SEMICOLON)) {
+ if (builder.getTokenType() == JavaTokenType.LBRACE) {
+ myParser.getStatementParser().parseCodeBlock(builder);
+ }
}
done(declaration, anno ? JavaElementType.ANNOTATION_METHOD : JavaElementType.METHOD);
@@ -445,24 +441,24 @@ public class DeclarationParser {
}
@NotNull
- public PsiBuilder.Marker parseParameterList(final PsiBuilder builder) {
- return parseElementList(builder, ListType.NORMAL);
+ public PsiBuilder.Marker parseParameterList(PsiBuilder builder) {
+ return parseElementList(builder, ListType.METHOD);
}
@NotNull
- public PsiBuilder.Marker parseResourceList(final PsiBuilder builder) {
+ public PsiBuilder.Marker parseResourceList(PsiBuilder builder) {
return parseElementList(builder, ListType.RESOURCE);
}
@NotNull
- public PsiBuilder.Marker parseLambdaParameterList(final PsiBuilder builder, final boolean typed) {
+ public PsiBuilder.Marker parseLambdaParameterList(PsiBuilder builder, boolean typed) {
return parseElementList(builder, typed ? ListType.LAMBDA_TYPED : ListType.LAMBDA_UNTYPED);
}
- private enum ListType { NORMAL, RESOURCE, LAMBDA_TYPED, LAMBDA_UNTYPED }
+ private enum ListType {METHOD, RESOURCE, LAMBDA_TYPED, LAMBDA_UNTYPED}
@NotNull
- private PsiBuilder.Marker parseElementList(final PsiBuilder builder, final ListType type) {
+ private PsiBuilder.Marker parseElementList(PsiBuilder builder, ListType type) {
final boolean lambda = (type == ListType.LAMBDA_TYPED || type == ListType.LAMBDA_UNTYPED);
final boolean resources = (type == ListType.RESOURCE);
final PsiBuilder.Marker elementList = builder.mark();
@@ -563,29 +559,25 @@ public class DeclarationParser {
}
@Nullable
- public PsiBuilder.Marker parseParameter(final PsiBuilder builder, final boolean ellipsis, final boolean disjunctiveType) {
+ public PsiBuilder.Marker parseParameter(PsiBuilder builder, boolean ellipsis, boolean disjunctiveType) {
return parseListElement(builder, true, ellipsis, disjunctiveType, false);
}
@Nullable
- public PsiBuilder.Marker parseResource(final PsiBuilder builder) {
+ public PsiBuilder.Marker parseResource(PsiBuilder builder) {
return parseListElement(builder, true, false, false, true);
}
@Nullable
- public PsiBuilder.Marker parseLambdaParameter(final PsiBuilder builder, final boolean typed) {
+ public PsiBuilder.Marker parseLambdaParameter(PsiBuilder builder, boolean typed) {
return parseListElement(builder, typed, true, false, false);
}
@Nullable
- private PsiBuilder.Marker parseListElement(final PsiBuilder builder,
- final boolean typed,
- final boolean ellipsis,
- final boolean disjunctiveType,
- final boolean resource) {
- final PsiBuilder.Marker param = builder.mark();
+ private PsiBuilder.Marker parseListElement(PsiBuilder builder, boolean typed, boolean ellipsis, boolean disjunctiveType, boolean resource) {
+ PsiBuilder.Marker param = builder.mark();
- final Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
+ Pair<PsiBuilder.Marker, Boolean> modListInfo = parseModifierList(builder);
ReferenceParser.TypeInfo typeInfo = null;
if (typed) {
@@ -608,7 +600,7 @@ public class DeclarationParser {
if (expect(builder, JavaTokenType.IDENTIFIER)) {
if (!resource) {
- eatBrackets(builder, typeInfo != null && typeInfo.isVarArg, "expected.rparen");
+ eatBrackets(builder, typeInfo != null && typeInfo.isVarArg ? "expected.rparen" : null);
done(param, JavaElementType.PARAMETER);
return param;
}
@@ -630,8 +622,7 @@ public class DeclarationParser {
}
@Nullable
- private PsiBuilder.Marker parseFieldOrLocalVariable(final PsiBuilder builder, final PsiBuilder.Marker declaration,
- final int declarationStart, final Context context) {
+ private PsiBuilder.Marker parseFieldOrLocalVariable(PsiBuilder builder, PsiBuilder.Marker declaration, int declarationStart, Context context) {
final IElementType varType;
if (context == Context.CLASS || context == Context.ANNOTATION_INTERFACE) {
varType = JavaElementType.FIELD;
@@ -653,7 +644,7 @@ public class DeclarationParser {
while (true) {
shouldRollback = true;
- if (!eatBrackets(builder, false, null)) {
+ if (!eatBrackets(builder, null)) {
unclosed = true;
}
@@ -715,26 +706,33 @@ public class DeclarationParser {
return declaration;
}
- private static boolean eatBrackets(final PsiBuilder builder, final boolean isError,
- @Nullable @PropertyKey(resourceBundle = JavaErrorMessages.BUNDLE) String errorKey) {
- if (builder.getTokenType() != JavaTokenType.LBRACKET) return true;
+ private boolean eatBrackets(PsiBuilder builder, @Nullable @PropertyKey(resourceBundle = JavaErrorMessages.BUNDLE) String errorKey) {
+ IElementType tokenType = builder.getTokenType();
+ if (tokenType != JavaTokenType.LBRACKET && tokenType != JavaTokenType.AT) return true;
- final PsiBuilder.Marker marker = isError ? builder.mark() : null;
+ PsiBuilder.Marker marker = errorKey != null ? builder.mark() : null;
- boolean result = true;
- while (expect(builder, JavaTokenType.LBRACKET)) {
+ int count = 0;
+ while (true) {
+ parseAnnotations(builder);
+ if (!expect(builder, JavaTokenType.LBRACKET)) {
+ break;
+ }
+ ++count;
if (!expect(builder, JavaTokenType.RBRACKET)) {
- if (!isError) error(builder, JavaErrorMessages.message("expected.rbracket"));
- result = false;
break;
}
+ ++count;
}
- if (marker != null && errorKey != null) {
+ boolean paired = count % 2 == 0;
+ if (marker != null) {
marker.error(JavaErrorMessages.message(errorKey));
}
-
- return result;
+ else if (!paired) {
+ error(builder, JavaErrorMessages.message("expected.rbracket"));
+ }
+ return paired;
}
@Nullable
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java
index e703c93d4a3c..34dd67d8ea1c 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java
@@ -332,7 +332,12 @@ public class ExpressionParser {
final int dotOffset = builder.getCurrentOffset();
builder.advanceLexer();
- final IElementType dotTokenType = builder.getTokenType();
+ IElementType dotTokenType = builder.getTokenType();
+ if (dotTokenType == JavaTokenType.AT) {
+ myParser.getDeclarationParser().parseAnnotations(builder);
+ dotTokenType = builder.getTokenType();
+ }
+
if (dotTokenType == JavaTokenType.CLASS_KEYWORD && exprType(expr) == JavaElementType.REFERENCE_EXPRESSION) {
if (breakPoint == BreakPoint.P1 && builder.getCurrentOffset() == breakOffset) {
error(builder, JavaErrorMessages.message("expected.identifier"));
@@ -691,9 +696,12 @@ public class ExpressionParser {
myParser.getReferenceParser().parseReferenceParameterList(builder, false, true);
PsiBuilder.Marker refOrType;
-
+ PsiBuilder.Marker anno = myParser.getDeclarationParser().parseAnnotations(builder);
IElementType tokenType = builder.getTokenType();
- if (tokenType == JavaTokenType.IDENTIFIER || tokenType == JavaTokenType.AT) {
+ if (tokenType == JavaTokenType.IDENTIFIER) {
+ if (anno != null) {
+ anno.rollbackTo();
+ }
refOrType = myParser.getReferenceParser().parseJavaCodeReference(builder, true, true, true, true);
if (refOrType == null) {
error(builder, JavaErrorMessages.message("expected.identifier"));
diff --git a/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java b/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
index 6e72f6017d2e..42a41d51c6fb 100644
--- a/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
+++ b/java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
@@ -74,7 +74,8 @@ public class ReferenceParser {
while (builder.getTokenType() == operator) {
builder.advanceLexer();
- if (builder.getTokenType() != JavaTokenType.IDENTIFIER) {
+ IElementType tokenType = builder.getTokenType();
+ if (tokenType != JavaTokenType.IDENTIFIER && tokenType != JavaTokenType.AT) {
error(builder, JavaErrorMessages.message("expected.identifier"));
}
parseTypeInfo(builder, flags, false);
@@ -269,7 +270,7 @@ public class ReferenceParser {
return false;
}
- final int flags = set(set(EAT_LAST_DOT, WILDCARD, wildcard), DIAMONDS, diamonds);
+ int flags = set(set(EAT_LAST_DOT, WILDCARD, wildcard), DIAMONDS, diamonds);
boolean isOk = true;
while (true) {
if (parseTypeInfo(builder, flags, true) == null) {
@@ -289,6 +290,7 @@ public class ReferenceParser {
isOk = false;
break;
}
+ flags = set(flags, DIAMONDS, false);
}
list.done(JavaElementType.REFERENCE_PARAMETER_LIST);
diff --git a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java
index dec7b71f5438..b14a37dfb4f3 100644
--- a/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/PsiDiamondTypeImpl.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi;
+import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
@@ -128,25 +129,31 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
if (psiClass == null) return DiamondInferenceResult.NULL_RESULT;
final PsiExpressionList argumentList = newExpression.getArgumentList();
if (argumentList == null) return DiamondInferenceResult.NULL_RESULT;
- final Ref<PsiMethod> staticFactory = new Ref<PsiMethod>();
- final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(newExpression, true, new Computable<PsiSubstitutor>() {
+ final Ref<PsiMethod> staticFactoryRef = new Ref<PsiMethod>();
+ final PsiSubstitutor inferredSubstitutor = ourDiamondGuard.doPreventingRecursion(newExpression, false, new Computable<PsiSubstitutor>() {
@Override
public PsiSubstitutor compute() {
final PsiMethod constructor = findConstructor(psiClass, newExpression);
PsiTypeParameter[] params = getAllTypeParams(constructor, psiClass);
- staticFactory.set(generateStaticFactory(constructor, psiClass, params));
- if (staticFactory.get() == null) {
+ final PsiMethod staticFactory = generateStaticFactory(constructor, psiClass, params);
+ if (staticFactory == null) {
return null;
}
+ staticFactoryRef.set(staticFactory);
- return inferTypeParametersForStaticFactory(staticFactory.get(), newExpression, context);
+ return inferTypeParametersForStaticFactory(staticFactory, newExpression, context);
}
});
if (inferredSubstitutor == null) {
return DiamondInferenceResult.NULL_RESULT;
}
- final PsiTypeParameter[] parameters = staticFactory.get().getTypeParameters();
+ final PsiMethod staticFactory = staticFactoryRef.get();
+ if (staticFactory == null) {
+ LOG.error(inferredSubstitutor);
+ return DiamondInferenceResult.NULL_RESULT;
+ }
+ final PsiTypeParameter[] parameters = staticFactory.getTypeParameters();
final PsiTypeParameter[] classParameters = psiClass.getTypeParameters();
final PsiJavaCodeReferenceElement classOrAnonymousClassReference = newExpression.getClassOrAnonymousClassReference();
LOG.assertTrue(classOrAnonymousClassReference != null);
@@ -210,7 +217,7 @@ public class PsiDiamondTypeImpl extends PsiDiamondType {
buf.append(StringUtil.join(params, new Function<PsiTypeParameter, String>() {
@Override
public String fun(PsiTypeParameter psiTypeParameter) {
- final String extendsList = psiTypeParameter.getExtendsList().getText();
+ final String extendsList = psiTypeParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE) ? psiTypeParameter.getExtendsList().getText() : null;
return psiTypeParameter.getName() + (StringUtil.isEmpty(extendsList) ? "" : " " + extendsList);
}
}, ", "));
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
index 8387b8cc35d0..7cc2bd234c35 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiClassImplUtil.java
@@ -480,10 +480,15 @@ public class PsiClassImplUtil {
if (list != null) {
for (final Pair<PsiMember, PsiSubstitutor> candidate : list) {
PsiMember candidateField = candidate.getFirst();
- PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(candidateField.getContainingClass(), candidate.getSecond(), aClass,
+ PsiClass containingClass = candidateField.getContainingClass();
+ if (containingClass == null) {
+ LOG.error("No class for field " + candidateField.getName() + " of " + candidateField.getClass());
+ continue;
+ }
+ PsiSubstitutor finalSubstitutor = obtainFinalSubstitutor(containingClass, candidate.getSecond(), aClass,
substitutor, factory, languageLevel);
- processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, candidateField.getContainingClass());
+ processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor))) return false;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java
index d8c271f1818e..f7a6d2ed0b24 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiElementFactoryImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -89,24 +89,22 @@ public class PsiElementFactoryImpl extends PsiJavaParserFacadeImpl implements Ps
@NotNull
@Override
- public PsiClassType createType(@NotNull final PsiClass resolve, @NotNull final PsiSubstitutor substitutor) {
+ public PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor) {
return new PsiImmediateClassType(resolve, substitutor);
}
@NotNull
@Override
- public PsiClassType createType(@NotNull final PsiClass resolve,
- @NotNull final PsiSubstitutor substitutor,
- @NotNull final LanguageLevel languageLevel) {
+ public PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel) {
return new PsiImmediateClassType(resolve, substitutor, languageLevel);
}
@NotNull
@Override
- public PsiClassType createType(@NotNull final PsiClass resolve,
- @NotNull final PsiSubstitutor substitutor,
- @NotNull final LanguageLevel languageLevel,
- @NotNull final PsiAnnotation[] annotations) {
+ public PsiClassType createType(@NotNull PsiClass resolve,
+ @NotNull PsiSubstitutor substitutor,
+ @Nullable LanguageLevel languageLevel,
+ @NotNull PsiAnnotation[] annotations) {
return new PsiImmediateClassType(resolve, substitutor, languageLevel, annotations);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
index 7975019df445..c1db5cd259a7 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,18 +46,38 @@ import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.PairFunction;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
+import java.util.Set;
+
+import static com.intellij.psi.PsiAnnotation.TargetType;
public class PsiImplUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.PsiImplUtil");
- private PsiImplUtil() {
- }
+ private static final Set<TargetType> DEFAULT_TARGETS = Collections.unmodifiableSet(ContainerUtil.newHashSet(
+ TargetType.PACKAGE, TargetType.TYPE, TargetType.ANNOTATION_TYPE,
+ TargetType.FIELD, TargetType.METHOD, TargetType.CONSTRUCTOR,
+ TargetType.PARAMETER, TargetType.LOCAL_VARIABLE));
+
+ private static final TargetType[] PACKAGE_TARGETS = {TargetType.PACKAGE};
+ private static final TargetType[] TYPE_USE_TARGETS = {TargetType.TYPE_USE};
+ private static final TargetType[] ANNOTATION_TARGETS = {TargetType.ANNOTATION_TYPE, TargetType.TYPE, TargetType.TYPE_USE};
+ private static final TargetType[] TYPE_TARGETS = {TargetType.TYPE, TargetType.TYPE_USE};
+ private static final TargetType[] TYPE_PARAMETER_TARGETS = {TargetType.TYPE_PARAMETER, TargetType.TYPE_USE};
+ private static final TargetType[] CONSTRUCTOR_TARGETS = {TargetType.CONSTRUCTOR, TargetType.TYPE_USE};
+ private static final TargetType[] METHOD_TARGETS = {TargetType.METHOD, TargetType.TYPE_USE};
+ private static final TargetType[] FIELD_TARGETS = {TargetType.FIELD, TargetType.TYPE_USE};
+ private static final TargetType[] PARAMETER_TARGETS = {TargetType.PARAMETER, TargetType.TYPE_USE};
+ private static final TargetType[] LOCAL_VARIABLE_TARGETS ={TargetType.LOCAL_VARIABLE, TargetType.TYPE_USE};
+
+ private PsiImplUtil() { }
@NotNull
public static PsiMethod[] getConstructors(@NotNull PsiClass aClass) {
@@ -142,7 +162,7 @@ public class PsiImplUtil {
int i;
for (i = parameters.length - 1; i >= 0; i--) {
PsiParameter paramInList = parameters[i];
- if (name.equals(paramInList.getName())) {
+ if (Comparing.equal(name, paramInList.getName())) {
suspect = paramInList;
break;
}
@@ -298,24 +318,155 @@ public class PsiImplUtil {
return new PsiImmediateClassType(classClass, substitutor);
}
- @Nullable public static PsiAnnotation findAnnotation(@NotNull PsiAnnotationOwner modifierList, @NotNull String qualifiedName) {
- PsiAnnotation[] annotations = modifierList.getAnnotations();
+ @Nullable
+ public static PsiAnnotation findAnnotation(@NotNull PsiAnnotationOwner annotationOwner, @NotNull String qualifiedName) {
+ PsiAnnotation[] annotations = annotationOwner.getAnnotations();
if (annotations.length == 0) {
return null;
}
- final String shortName = StringUtil.getShortName(qualifiedName);
+ String shortName = StringUtil.getShortName(qualifiedName);
for (PsiAnnotation annotation : annotations) {
- final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
+ PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
if (referenceElement != null && shortName.equals(referenceElement.getReferenceName())) {
- if (qualifiedName.equals(annotation.getQualifiedName())) return annotation;
+ if (qualifiedName.equals(annotation.getQualifiedName())) {
+ return annotation;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Nullable
+ public static TargetType findApplicableTarget(@NotNull PsiAnnotation annotation, @NotNull TargetType... types) {
+ if (types.length != 0) {
+ PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
+ if (ref != null) {
+ PsiElement annotationType = ref.resolve();
+ if (annotationType instanceof PsiClass) {
+ return findApplicableTarget((PsiClass)annotationType, types);
+ }
+ }
+ }
+
+ return TargetType.UNKNOWN;
+ }
+
+ @Nullable
+ public static TargetType findApplicableTarget(@NotNull PsiClass annotationType, @NotNull TargetType... types) {
+ if (types.length != 0) {
+ Set<TargetType> targets = getAnnotationTargets(annotationType);
+ if (targets != null) {
+ for (TargetType type : types) {
+ if (type != TargetType.UNKNOWN && targets.contains(type)) {
+ return type;
+ }
+ }
+ return null;
+ }
+ }
+
+ return TargetType.UNKNOWN;
+ }
+
+ // todo[r.sh] cache?
+ @Nullable
+ private static Set<TargetType> getAnnotationTargets(PsiClass annotationType) {
+ if (!annotationType.isAnnotationType()) return null;
+ PsiModifierList modifierList = annotationType.getModifierList();
+ if (modifierList == null) return null;
+ PsiAnnotation target = modifierList.findAnnotation(CommonClassNames.TARGET_ANNOTATION_FQ_NAME);
+ if (target == null) return DEFAULT_TARGETS; // if omitted it is applicable to all but Java 8 TYPE_USE/TYPE_PARAMETERS targets
+
+ PsiAnnotationMemberValue value = target.findAttributeValue(null);
+ if (value instanceof PsiReference) {
+ TargetType targetType = translateTargetRef((PsiReference)value);
+ if (targetType != null) {
+ return Collections.singleton(targetType);
+ }
+ }
+ else if (value instanceof PsiArrayInitializerMemberValue) {
+ Set <TargetType> targets = ContainerUtil.newHashSet();
+ for (PsiAnnotationMemberValue initializer : ((PsiArrayInitializerMemberValue)value).getInitializers()) {
+ if (initializer instanceof PsiReference) {
+ TargetType targetType = translateTargetRef((PsiReference)initializer);
+ if (targetType != null) {
+ targets.add(targetType);
+ }
+ }
}
+ return targets;
}
return null;
}
@Nullable
+ private static TargetType translateTargetRef(PsiReference reference) {
+ PsiElement field = reference.resolve();
+ if (field instanceof PsiEnumConstant) {
+ String name = ((PsiEnumConstant)field).getName();
+ try {
+ return TargetType.valueOf(name);
+ }
+ catch (IllegalArgumentException e) {
+ LOG.warn("Unknown target: " + name);
+ }
+ }
+ return null;
+ }
+
+ @NotNull
+ public static TargetType[] getTargetsForLocation(@Nullable PsiAnnotationOwner owner) {
+ if (owner == null) {
+ return TargetType.EMPTY_ARRAY;
+ }
+
+ if (owner instanceof PsiType || owner instanceof PsiTypeElement) {
+ return TYPE_USE_TARGETS;
+ }
+
+ if (owner instanceof PsiTypeParameter) {
+ return TYPE_PARAMETER_TARGETS;
+ }
+
+ if (owner instanceof PsiModifierList) {
+ PsiElement element = ((PsiModifierList)owner).getParent();
+ if (element instanceof PsiPackageStatement) {
+ return PACKAGE_TARGETS;
+ }
+ if (element instanceof PsiClass) {
+ if (((PsiClass)element).isAnnotationType()) {
+ return ANNOTATION_TARGETS;
+ }
+ else {
+ return TYPE_TARGETS;
+ }
+ }
+ if (element instanceof PsiMethod) {
+ if (((PsiMethod)element).isConstructor()) {
+ return CONSTRUCTOR_TARGETS;
+ }
+ else {
+ return METHOD_TARGETS;
+ }
+ }
+ if (element instanceof PsiField) {
+ return FIELD_TARGETS;
+ }
+ if (element instanceof PsiParameter) {
+ return PARAMETER_TARGETS;
+ }
+ if (element instanceof PsiLocalVariable) {
+ return LOCAL_VARIABLE_TARGETS;
+ }
+ }
+
+ return TargetType.EMPTY_ARRAY;
+ }
+
+ @Nullable
public static ASTNode findDocComment(@NotNull CompositeElement element) {
TreeElement node = element.getFirstChildNode();
while (node != null && (isWhitespaceOrComment(node) && !(node.getPsi() instanceof PsiDocComment))) {
@@ -566,4 +717,34 @@ public class PsiImplUtil {
public static PsiElement handleMirror(PsiElement element) {
return element instanceof PsiMirrorElement ? ((PsiMirrorElement)element).getPrototype() : element;
}
+
+ @Nullable
+ public static PsiModifierList findNeighbourModifierList(@NotNull PsiJavaCodeReferenceElement ref) {
+ PsiElement parent = PsiTreeUtil.skipParentsOfType(ref, PsiJavaCodeReferenceElement.class);
+ if (parent instanceof PsiTypeElement) {
+ PsiElement grandParent = parent.getParent();
+ if (grandParent instanceof PsiModifierListOwner) {
+ return ((PsiModifierListOwner)grandParent).getModifierList();
+ }
+ }
+
+ return null;
+ }
+
+ public static void addTypeUseAnnotationsFromModifierList(@NotNull PsiElement member, @NotNull List<PsiAnnotation> annotations) {
+ if (member instanceof PsiModifierListOwner) {
+ PsiModifierList modifierList = ((PsiModifierListOwner)member).getModifierList();
+ if (modifierList != null) {
+ addTypeUseAnnotations(modifierList, annotations);
+ }
+ }
+ }
+
+ public static void addTypeUseAnnotations(@NotNull PsiModifierList modifierList, @NotNull List<PsiAnnotation> annotations) {
+ for (PsiAnnotation annotation : modifierList.getAnnotations()) {
+ if (findApplicableTarget(annotation, TargetType.TYPE_USE) == TargetType.TYPE_USE) {
+ annotations.add(annotation);
+ }
+ }
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java
index 62c051427569..1b72ac983e9b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/ModifierFlags.java
@@ -38,10 +38,9 @@ public final class ModifierFlags {
public static final int STRICTFP_MASK = 0x0800;
public static final int PACKAGE_LOCAL_MASK = 0x1000;
- public static final TObjectIntHashMap<String> NAME_TO_MODIFIER_FLAG_MAP;
- public static final TObjectIntHashMap<IElementType> KEYWORD_TO_MODIFIER_FLAG_MAP;
+ public static final TObjectIntHashMap<String> NAME_TO_MODIFIER_FLAG_MAP = new TObjectIntHashMap<String>();
+ public static final TObjectIntHashMap<IElementType> KEYWORD_TO_MODIFIER_FLAG_MAP = new TObjectIntHashMap<IElementType>();
static {
- NAME_TO_MODIFIER_FLAG_MAP = new TObjectIntHashMap<String>();
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PUBLIC, PUBLIC_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PRIVATE, PRIVATE_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PROTECTED, PROTECTED_MASK);
@@ -56,7 +55,6 @@ public final class ModifierFlags {
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.STRICTFP, STRICTFP_MASK);
NAME_TO_MODIFIER_FLAG_MAP.put(PsiModifier.PACKAGE_LOCAL, PACKAGE_LOCAL_MASK);
- KEYWORD_TO_MODIFIER_FLAG_MAP = new TObjectIntHashMap<IElementType>();
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.PUBLIC_KEYWORD, PUBLIC_MASK);
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.PRIVATE_KEYWORD, PRIVATE_MASK);
KEYWORD_TO_MODIFIER_FLAG_MAP.put(JavaTokenType.PROTECTED_KEYWORD, PROTECTED_MASK);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java
index a311b48a80dd..e0c09866c813 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/RecordUtil.java
@@ -18,9 +18,10 @@ package com.intellij.psi.impl.cache;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
import com.intellij.lang.LighterASTTokenNode;
-import com.intellij.psi.*;
+import com.intellij.psi.JavaTokenType;
+import com.intellij.psi.PsiModifier;
+import com.intellij.psi.PsiModifierList;
import com.intellij.psi.impl.java.stubs.*;
-import com.intellij.psi.impl.java.stubs.impl.PsiMethodStubImpl;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.LightTreeUtil;
import com.intellij.psi.stubs.PsiFileStub;
@@ -110,12 +111,7 @@ public class RecordUtil {
else if (parent instanceof PsiMethodStub) {
if (grandParent instanceof PsiClassStub && ((PsiClassStub)grandParent).isInterface()) {
packed |= ModifierFlags.PUBLIC_MASK;
- if (parent instanceof PsiMethodStubImpl && ((PsiMethodStubImpl)parent).hasExtensionMethodMark()) {
- packed |= ModifierFlags.DEFENDER_MASK;
- }
- else {
- packed |= ModifierFlags.ABSTRACT_MASK;
- }
+ packed |= ModifierFlags.ABSTRACT_MASK;
}
}
else if (parent instanceof PsiFieldStub) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
index 0b4dc267bf66..d9d3b0612133 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
@@ -17,96 +17,102 @@ package com.intellij.psi.impl.cache;
import com.intellij.lang.LighterAST;
import com.intellij.lang.LighterASTNode;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiNameHelper;
+import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiAnnotationStub;
import com.intellij.psi.impl.java.stubs.PsiClassStub;
+import com.intellij.psi.impl.java.stubs.PsiModifierListStub;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.LightTreeUtil;
+import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream;
import com.intellij.psi.tree.IElementType;
-import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.StringRef;
-import gnu.trove.TIntObjectHashMap;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
+import static com.intellij.psi.PsiAnnotation.TargetType;
import static com.intellij.util.BitUtil.isSet;
/**
* @author max
*/
public class TypeInfo {
- private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.cache.TypeInfo");
-
- private static final TIntObjectHashMap<String> ourIndexFrequentType = new TIntObjectHashMap<String>();
- private static final TObjectIntHashMap<String> ourFrequentTypeIndex = new TObjectIntHashMap<String>();
-
- private static void registerFrequentType(String typeText) {
- int index = ourFrequentTypeIndex.size() + 1;
- assert index > 0 && index < 15 : "reserved: " + index + " (" + typeText + ")";
- ourFrequentTypeIndex.put(typeText, index);
- ourIndexFrequentType.put(index, typeText);
- }
+ private static final String[] ourIndexFrequentType;
+ private static final TObjectIntHashMap<String> ourFrequentTypeIndex;
static {
- registerFrequentType("boolean");
- registerFrequentType("byte");
- registerFrequentType("char");
- registerFrequentType("double");
- registerFrequentType("float");
- registerFrequentType("int");
- registerFrequentType("long");
- registerFrequentType("null");
- registerFrequentType("short");
- registerFrequentType("void");
- registerFrequentType("Object");
- registerFrequentType(CommonClassNames.JAVA_LANG_OBJECT);
- registerFrequentType("String");
- registerFrequentType(CommonClassNames.JAVA_LANG_STRING);
+ ourIndexFrequentType = new String[]{
+ "",
+ "boolean",
+ "byte",
+ "char",
+ "double",
+ "float",
+ "int",
+ "long",
+ "null",
+ "short",
+ "void",
+ CommonClassNames.JAVA_LANG_OBJECT_SHORT, CommonClassNames.JAVA_LANG_OBJECT,
+ CommonClassNames.JAVA_LANG_STRING_SHORT, CommonClassNames.JAVA_LANG_STRING
+ };
+
+ ourFrequentTypeIndex = new TObjectIntHashMap<String>();
+ for (int i = 0; i < ourIndexFrequentType.length; i++) {
+ String type = ourIndexFrequentType[i];
+ ourFrequentTypeIndex.put(type, i);
+ }
}
- private static final int NULL_FLAGS = 0x0F;
- private static final int FREQUENT_INDEX_MASK = 0x0F;
- private static final int HAS_ANNOTATIONS = 0x10;
- private static final int HAS_ARRAY_COUNT = 0x20;
- private static final int HAS_ELLIPSIS = 0x40;
+ private static final int FREQUENT_INDEX_MASK = 0x03F;
+ private static final int HAS_ARRAY_COUNT = 0x40;
+ private static final int HAS_ELLIPSIS = 0x80;
- private static final TypeInfo NULL = new TypeInfo(null, (byte)0, false, Collections.<PsiAnnotationStub>emptyList());
+ private static final TypeInfo NULL = new TypeInfo((StringRef)null, (byte)0, false, ContainerUtil.<PsiAnnotationStub>emptyList());
public final StringRef text;
public final byte arrayCount;
public final boolean isEllipsis;
+
private final List<PsiAnnotationStub> myAnnotationStubs;
- public TypeInfo(StringRef _text, byte _arrayCount, boolean ellipsis, @NotNull List<PsiAnnotationStub> annotationStubs) {
- text = _text;
- arrayCount = _arrayCount;
- isEllipsis = ellipsis;
- myAnnotationStubs = annotationStubs;
+ public TypeInfo(String text, byte arrayCount, boolean ellipsis, @NotNull List<PsiAnnotationStub> annotationStubs) {
+ this(StringRef.fromString(text == null ? null : internFrequentType(text)), arrayCount, ellipsis, annotationStubs);
}
- public TypeInfo(@NotNull TypeInfo typeInfo) {
- text = typeInfo.text;
- arrayCount = typeInfo.arrayCount;
- isEllipsis = typeInfo.isEllipsis;
- myAnnotationStubs = new SmartList<PsiAnnotationStub>(typeInfo.myAnnotationStubs);
+ private TypeInfo(StringRef text, byte arrayCount, boolean isEllipsis, @NotNull List<PsiAnnotationStub> annotationStubs) {
+ this.text = text;
+ this.arrayCount = arrayCount;
+ this.isEllipsis = isEllipsis;
+ myAnnotationStubs = annotationStubs;
}
- public void addAnnotation(PsiAnnotationStub annotation) {
- myAnnotationStubs.add(annotation);
+ @NotNull
+ public TypeInfo applyAnnotations(@NotNull StubBase<?> owner) {
+ PsiModifierListStub modifierList = (PsiModifierListStub)owner.findChildStubByType(JavaStubElementTypes.MODIFIER_LIST);
+ if (modifierList == null) return this;
+
+ List<PsiAnnotationStub> annotationStubs = ContainerUtil.newArrayList();
+ for (StubElement child : modifierList.getChildrenStubs()) {
+ if (!(child instanceof PsiAnnotationStub)) continue;
+ PsiAnnotationStub annotationStub = (PsiAnnotationStub)child;
+ if (PsiImplUtil.findApplicableTarget(annotationStub.getPsiElement(), TargetType.TYPE_USE) == TargetType.TYPE_USE) {
+ annotationStubs.add(annotationStub);
+ }
+ }
+ return new TypeInfo(text, arrayCount, isEllipsis, annotationStubs);
}
@NotNull
@@ -135,7 +141,7 @@ public class TypeInfo {
@NotNull
public static TypeInfo create(@NotNull LighterAST tree, @NotNull LighterASTNode element, StubElement parentStub) {
String text;
- int arrayCount = 0;
+ byte arrayCount = 0;
boolean isEllipsis = false;
if (element.getTokenType() == JavaElementType.ENUM_CONSTANT) {
@@ -166,7 +172,7 @@ public class TypeInfo {
assert typeElement != null : element + " in " + parentStub;
- isEllipsis = (LightTreeUtil.firstChildOfType(tree, typeElement, JavaTokenType.ELLIPSIS) != null);
+ isEllipsis = LightTreeUtil.firstChildOfType(tree, typeElement, JavaTokenType.ELLIPSIS) != null;
while (true) {
LighterASTNode nested = LightTreeUtil.firstChildOfType(tree, typeElement, JavaElementType.TYPE);
@@ -178,9 +184,7 @@ public class TypeInfo {
text = LightTreeUtil.toFilteredString(tree, typeElement, null);
}
- List<PsiAnnotationStub> annotations = Collections.emptyList(); // todo[r.sh] JDK 8 type annotations
-
- return new TypeInfo(StringRef.fromString(text), (byte)arrayCount, isEllipsis, annotations);
+ return new TypeInfo(text, arrayCount, isEllipsis, ContainerUtil.<PsiAnnotationStub>emptyList());
}
@NotNull
@@ -193,9 +197,7 @@ public class TypeInfo {
typeText = typeText.substring(0, typeText.length() - 2);
}
- StringRef text = StringRef.fromString(typeText);
-
- return new TypeInfo(text, arrayCount, isEllipsis, Collections.<PsiAnnotationStub>emptyList());
+ return new TypeInfo(typeText, arrayCount, isEllipsis, ContainerUtil.<PsiAnnotationStub>emptyList());
}
@NotNull
@@ -210,66 +212,40 @@ public class TypeInfo {
}
@NotNull
- public static TypeInfo readTYPE(@NotNull StubInputStream record, StubElement parentStub) throws IOException {
+ public static TypeInfo readTYPE(@NotNull StubInputStream record) throws IOException {
int flags = 0xFF & record.readByte();
- if (flags == NULL_FLAGS) {
+ if (flags == FREQUENT_INDEX_MASK) {
return NULL;
}
int frequentIndex = FREQUENT_INDEX_MASK & flags;
- boolean hasAnnotations = isSet(flags, HAS_ANNOTATIONS);
byte arrayCount = isSet(flags, HAS_ARRAY_COUNT) ? record.readByte() : 0;
boolean hasEllipsis = isSet(flags, HAS_ELLIPSIS);
- StringRef text = frequentIndex == 0 ? record.readName() : StringRef.fromString(ourIndexFrequentType.get(frequentIndex));
+ StringRef text = frequentIndex == 0 ? record.readName() : StringRef.fromString(ourIndexFrequentType[frequentIndex]);
- List<PsiAnnotationStub> annotationStubs;
- if (hasAnnotations) {
- int size = 0xFF & record.readByte();
- annotationStubs = new ArrayList<PsiAnnotationStub>(size);
- for (int i = 0; i < size; i++) {
- PsiAnnotationStub annotationStub = JavaStubElementTypes.ANNOTATION.deserialize(record, parentStub);
- annotationStubs.add(annotationStub);
- }
- }
- else {
- annotationStubs = Collections.emptyList();
- }
-
- return new TypeInfo(text, arrayCount, hasEllipsis, annotationStubs);
+ return new TypeInfo(text, arrayCount, hasEllipsis, ContainerUtil.<PsiAnnotationStub>emptyList());
}
public static void writeTYPE(@NotNull StubOutputStream dataStream, @NotNull TypeInfo typeInfo) throws IOException {
if (typeInfo == NULL) {
- dataStream.writeByte(NULL_FLAGS);
+ dataStream.writeByte(FREQUENT_INDEX_MASK);
return;
}
- boolean hasEllipsis = typeInfo.isEllipsis;
String text = typeInfo.text.getString();
byte arrayCount = typeInfo.arrayCount;
int frequentIndex = ourFrequentTypeIndex.get(text);
- List<PsiAnnotationStub> annotations = typeInfo.myAnnotationStubs;
- boolean hasAnnotations = !annotations.isEmpty();
- int flags = (hasEllipsis ? HAS_ELLIPSIS : 0) |
- (arrayCount != 0 ? HAS_ARRAY_COUNT : 0) |
- (hasAnnotations ? HAS_ANNOTATIONS : 0) |
- frequentIndex;
-
+ int flags = (typeInfo.isEllipsis ? HAS_ELLIPSIS : 0) | (arrayCount != 0 ? HAS_ARRAY_COUNT : 0) | frequentIndex;
dataStream.writeByte(flags);
+
if (arrayCount != 0) {
dataStream.writeByte(arrayCount);
}
+
if (frequentIndex == 0) {
dataStream.writeName(text);
}
- if (hasAnnotations) {
- LOG.assertTrue(annotations.size() < 256, annotations.size());
- dataStream.writeByte(annotations.size());
- for (PsiAnnotationStub annotation : annotations) {
- dataStream.writeUTFFast(annotation.getText());
- }
- }
}
@Nullable
@@ -284,7 +260,7 @@ public class TypeInfo {
StringBuilder buf = new StringBuilder();
for (PsiAnnotationStub stub : typeInfo.myAnnotationStubs) {
- buf.append(stub.getText()).append(" ");
+ buf.append(stub.getText()).append(' ');
}
buf.append(typeInfo.text.getString());
@@ -299,4 +275,10 @@ public class TypeInfo {
return buf.toString();
}
+
+ @NotNull
+ private static String internFrequentType(@NotNull String type) {
+ int frequentIndex = ourFrequentTypeIndex.get(type);
+ return frequentIndex == 0 ? type : ourIndexFrequentType[frequentIndex];
+ }
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
index b9de2ddf6b94..f8877b9a787b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/StubBuildingVisitor.java
@@ -364,13 +364,13 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
}
@NotNull
- private static TypeInfo fieldTypeViaDescription(final String desc) {
+ private static TypeInfo fieldTypeViaDescription(@NotNull String desc) {
Type type = Type.getType(desc);
final int dim = type.getSort() == Type.ARRAY ? type.getDimensions() : 0;
if (dim > 0) {
type = type.getElementType();
}
- return new TypeInfo(StringRef.fromString(getTypeText(type)), (byte)dim, false, Collections.<PsiAnnotationStub>emptyList()); //todo read annos from .class file
+ return new TypeInfo(getTypeText(type), (byte)dim, false, Collections.<PsiAnnotationStub>emptyList()); //todo read annos from .class file
}
@Override
@@ -755,13 +755,14 @@ public class StubBuildingVisitor<T> extends ClassVisitor {
return getTypeText(Type.getObjectType(name));
}
- private static String getTypeText(final Type type) {
+ @NotNull
+ private static String getTypeText(@NotNull Type type) {
final String raw = type.getClassName();
// As the '$' char is a valid java identifier and is actively used by byte code generators, the problem is
// which occurrences of this char should be replaced and which should not.
// Heuristic: replace only those $ occurrences that are surrounded non-"$" chars
// (most likely generated by javac to separate inner or anonymous class name)
// Leading and trailing $ chars should be left unchanged.
- return raw.contains("$")? REGEX_PATTERN.matcher(raw).replaceAll("\\.") : raw;
+ return raw.indexOf('$') >= 0 ? REGEX_PATTERN.matcher(raw).replaceAll("\\.") : raw;
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java
index 962e371793b3..e5c7e455b124 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaAnnotationElementType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ 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.PsiAnnotation;
import com.intellij.psi.PsiNameHelper;
import com.intellij.psi.impl.java.stubs.impl.PsiAnnotationStubImpl;
@@ -48,42 +49,42 @@ public class JavaAnnotationElementType extends JavaStubElementType<PsiAnnotation
}
@Override
- public PsiAnnotation createPsi(@NotNull final PsiAnnotationStub stub) {
+ public PsiAnnotation createPsi(@NotNull PsiAnnotationStub stub) {
return getPsiFactory(stub).createAnnotation(stub);
}
@Override
- public PsiAnnotation createPsi(@NotNull final ASTNode node) {
+ public PsiAnnotation createPsi(@NotNull ASTNode node) {
return new PsiAnnotationImpl(node);
- }
+ }
@Override
- public PsiAnnotationStub createStub(final LighterAST tree, final LighterASTNode node, final StubElement parentStub) {
- final String text = LightTreeUtil.toFilteredString(tree, node, null);
+ public PsiAnnotationStub createStub(LighterAST tree, LighterASTNode node, StubElement parentStub) {
+ String text = LightTreeUtil.toFilteredString(tree, node, null);
return new PsiAnnotationStubImpl(parentStub, text);
}
@Override
- public void serialize(final PsiAnnotationStub stub, final StubOutputStream dataStream) throws IOException {
+ public void serialize(PsiAnnotationStub stub, StubOutputStream dataStream) throws IOException {
dataStream.writeUTFFast(stub.getText());
}
@Override
- public PsiAnnotationStub deserialize(final StubInputStream dataStream, final StubElement parentStub) throws IOException {
+ public PsiAnnotationStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
return new PsiAnnotationStubImpl(parentStub, dataStream.readUTFFast());
}
@Override
- public void indexStub(final PsiAnnotationStub stub, final IndexSink sink) {
- final String refText = getReferenceShortName(stub.getText());
- sink.occurrence(JavaStubIndexKeys.ANNOTATIONS, refText);
+ public void indexStub(PsiAnnotationStub stub, IndexSink sink) {
+ String shortName = getReferenceShortName(stub.getText());
+ if (!StringUtil.isEmptyOrSpaces(shortName)) {
+ sink.occurrence(JavaStubIndexKeys.ANNOTATIONS, shortName);
+ }
}
private static String getReferenceShortName(String annotationText) {
- final int index = annotationText.indexOf('('); //to get the text of reference itself
- if (index >= 0) {
- return PsiNameHelper.getShortClassName(annotationText.substring(0, index));
- }
+ int index = annotationText.indexOf('(');
+ if (index >= 0) annotationText = annotationText.substring(0, index);
return PsiNameHelper.getShortClassName(annotationText);
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassReferenceListElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassReferenceListElementType.java
index ac54dad9be11..9b27c364b9c6 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassReferenceListElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassReferenceListElementType.java
@@ -26,7 +26,6 @@ import com.intellij.psi.impl.java.stubs.index.JavaStubIndexKeys;
import com.intellij.psi.impl.source.PsiReferenceListImpl;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.impl.source.tree.LightTreeUtil;
-import com.intellij.psi.impl.source.tree.java.PsiTypeParameterExtendsBoundsListImpl;
import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
@@ -55,12 +54,7 @@ public abstract class JavaClassReferenceListElementType extends JavaStubElementT
@Override
public PsiReferenceList createPsi(@NotNull ASTNode node) {
- if (node.getElementType() == JavaStubElementTypes.EXTENDS_BOUND_LIST) {
- return new PsiTypeParameterExtendsBoundsListImpl(node);
- }
- else {
- return new PsiReferenceListImpl(node);
- }
+ return new PsiReferenceListImpl(node);
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaFieldStubElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaFieldStubElementType.java
index dee93f5db61d..86efe98490a5 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaFieldStubElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaFieldStubElementType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -127,7 +127,7 @@ public abstract class JavaFieldStubElementType extends JavaStubElementType<PsiFi
@Override
public PsiFieldStub deserialize(final StubInputStream dataStream, final StubElement parentStub) throws IOException {
final StringRef name = dataStream.readName();
- final TypeInfo type = TypeInfo.readTYPE(dataStream, parentStub);
+ final TypeInfo type = TypeInfo.readTYPE(dataStream);
final StringRef initializerText = dataStream.readName();
final byte flags = dataStream.readByte();
return new PsiFieldStubImpl(parentStub, name, type, initializerText, flags);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java
index ba18473db823..bfaf99d8c22e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -73,7 +73,6 @@ public abstract class JavaMethodElementType extends JavaStubElementType<PsiMetho
boolean isVarArgs = false;
boolean isDeprecatedByComment = false;
boolean hasDeprecatedAnnotation = false;
- boolean isExtension = false;
String defValueText = null;
boolean expectingDef = false;
@@ -103,24 +102,18 @@ public abstract class JavaMethodElementType extends JavaStubElementType<PsiMetho
else if (type == JavaTokenType.DEFAULT_KEYWORD) {
expectingDef = true;
}
- else if (expectingDef && !ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(type) && type != JavaTokenType.SEMICOLON) {
- if (type != JavaElementType.CODE_BLOCK) {
- defValueText = LightTreeUtil.toFilteredString(tree, child, null);
- }
- else {
- isExtension = true;
- }
+ else if (expectingDef && !ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(type) &&
+ type != JavaTokenType.SEMICOLON && type != JavaElementType.CODE_BLOCK) {
+ defValueText = LightTreeUtil.toFilteredString(tree, child, null);
break;
}
}
- final TypeInfo typeInfo = isConstructor ? TypeInfo.createConstructorType() : TypeInfo.create(tree, node, parentStub);
- final boolean isAnno = (node.getTokenType() == JavaElementType.ANNOTATION_METHOD);
- final byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnno, isVarArgs, isDeprecatedByComment, hasDeprecatedAnnotation);
+ TypeInfo typeInfo = isConstructor ? TypeInfo.createConstructorType() : TypeInfo.create(tree, node, parentStub);
+ boolean isAnno = (node.getTokenType() == JavaElementType.ANNOTATION_METHOD);
+ byte flags = PsiMethodStubImpl.packFlags(isConstructor, isAnno, isVarArgs, isDeprecatedByComment, hasDeprecatedAnnotation);
- final PsiMethodStubImpl stub = new PsiMethodStubImpl(parentStub, StringRef.fromString(name), typeInfo, flags, StringRef.fromString(defValueText));
- stub.setExtensionMethodMark(isExtension);
- return stub;
+ return new PsiMethodStubImpl(parentStub, StringRef.fromString(name), typeInfo, flags, StringRef.fromString(defValueText));
}
@Override
@@ -136,7 +129,7 @@ public abstract class JavaMethodElementType extends JavaStubElementType<PsiMetho
@Override
public PsiMethodStub deserialize(final StubInputStream dataStream, final StubElement parentStub) throws IOException {
StringRef name = dataStream.readName();
- final TypeInfo type = TypeInfo.readTYPE(dataStream, parentStub);
+ final TypeInfo type = TypeInfo.readTYPE(dataStream);
byte flags = dataStream.readByte();
final StringRef defaultMethodValue = PsiMethodStubImpl.isAnnotationMethod(flags) ? dataStream.readName() : null;
return new PsiMethodStubImpl(parentStub, name, type, flags, defaultMethodValue);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaParameterElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaParameterElementType.java
index f9ebdd67b767..d0e79dd68a58 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaParameterElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaParameterElementType.java
@@ -76,7 +76,7 @@ public abstract class JavaParameterElementType extends JavaStubElementType<PsiPa
@Override
public PsiParameterStub deserialize(StubInputStream dataStream, StubElement parentStub) throws IOException {
StringRef name = dataStream.readName();
- TypeInfo type = TypeInfo.readTYPE(dataStream, parentStub);
+ TypeInfo type = TypeInfo.readTYPE(dataStream);
boolean isEllipsis = dataStream.readBoolean();
return new PsiParameterStubImpl(parentStub, name, type, isEllipsis);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/SourceStubPsiFactory.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/SourceStubPsiFactory.java
index d64f7afff81e..f3aa46edc64a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/SourceStubPsiFactory.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/SourceStubPsiFactory.java
@@ -47,10 +47,6 @@ public class SourceStubPsiFactory extends StubPsiFactory {
@Override
public PsiReferenceList createClassReferenceList(PsiClassReferenceListStub stub) {
- if (stub.getRole() == PsiReferenceList.Role.EXTENDS_BOUNDS_LIST) {
- return new PsiTypeParameterExtendsBoundsListImpl(stub, JavaStubElementTypes.EXTENDS_BOUND_LIST);
- }
-
return new PsiReferenceListImpl(stub, stub.getStubType());
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiAnnotationStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiAnnotationStubImpl.java
index 0f677e127aee..3262f35b2d5c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiAnnotationStubImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiAnnotationStubImpl.java
@@ -15,21 +15,18 @@
*/
package com.intellij.psi.impl.java.stubs.impl;
+import com.intellij.codeInsight.AnnotationUtil;
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.PsiJavaParserFacade;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiAnnotationStub;
+import com.intellij.psi.impl.source.CharTableImpl;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.reference.SoftReference;
import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.io.StringRef;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
/**
* @author max
@@ -41,18 +38,16 @@ public class PsiAnnotationStubImpl extends StubBase<PsiAnnotation> implements Ps
private SoftReference<PsiAnnotation> myParsedFromRepository;
public PsiAnnotationStubImpl(final StubElement parent, final String text) {
- this(parent, text, null);
+ super(parent, JavaStubElementTypes.ANNOTATION);
+ CharSequence interned = CharTableImpl.getStaticInterned(text);
+ myText = interned == null ? text : interned.toString();
}
- 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));
- }
- }
+ static {
+ CharTableImpl.addStringsFromClassToStatics(AnnotationUtil.class);
+ CharTableImpl.staticIntern("@NotNull");
+ CharTableImpl.staticIntern("@Nullable");
+ CharTableImpl.staticIntern("@Override");
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiFieldStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiFieldStubImpl.java
index b4383c1c73a3..d4ef43b96632 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiFieldStubImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiFieldStubImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,10 +18,7 @@ package com.intellij.psi.impl.java.stubs.impl;
import com.intellij.psi.PsiField;
import com.intellij.psi.impl.cache.TypeInfo;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
-import com.intellij.psi.impl.java.stubs.PsiAnnotationStub;
import com.intellij.psi.impl.java.stubs.PsiFieldStub;
-import com.intellij.psi.impl.java.stubs.PsiModifierListStub;
-import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.io.StringRef;
@@ -41,13 +38,12 @@ public class PsiFieldStubImpl extends StubBase<PsiField> implements PsiFieldStub
private static final int DEPRECATED = 0x02;
private static final int DEPRECATED_ANNOTATION = 0x04;
- public PsiFieldStubImpl(final StubElement parent, final String name, @NotNull TypeInfo type, @Nullable String initializer, final byte flags) {
+ public PsiFieldStubImpl(StubElement parent, String name, @NotNull TypeInfo type, @Nullable String initializer, byte flags) {
this(parent, StringRef.fromString(name), type, StringRef.fromString(initializer), flags);
}
- public PsiFieldStubImpl(final StubElement parent, final StringRef name, @NotNull TypeInfo type, final StringRef initializer, final byte flags) {
+ public PsiFieldStubImpl(StubElement parent, StringRef name, @NotNull TypeInfo type, @Nullable StringRef initializer, byte flags) {
super(parent, isEnumConst(flags) ? JavaStubElementTypes.ENUM_CONSTANT : JavaStubElementTypes.FIELD);
-
myName = name;
myType = type;
myInitializer = initializer;
@@ -57,24 +53,7 @@ public class PsiFieldStubImpl extends StubBase<PsiField> implements PsiFieldStub
@Override
@NotNull
public TypeInfo getType(boolean doResolve) {
- if (!doResolve) return myType;
-
- return addApplicableTypeAnnotationsFromChildModifierList(this, myType);
- }
-
- public static TypeInfo addApplicableTypeAnnotationsFromChildModifierList(StubBase<?> aThis, TypeInfo type) {
- PsiModifierListStub modifierList = (PsiModifierListStub)aThis.findChildStubByType(JavaStubElementTypes.MODIFIER_LIST);
- if (modifierList == null) return type;
- TypeInfo typeInfo = new TypeInfo(type);
- for (StubElement child: modifierList.getChildrenStubs()){
- if (!(child instanceof PsiAnnotationStub)) continue;
- PsiAnnotationStub annotationStub = (PsiAnnotationStub)child;
- PsiAnnotationImpl annotation = (PsiAnnotationImpl)annotationStub.getPsiElement();
- if (PsiAnnotationImpl.isAnnotationApplicableTo(annotation, true, "TYPE_USE")) {
- typeInfo.addAnnotation(annotationStub);
- }
- }
- return typeInfo;
+ return doResolve ? myType.applyAnnotations(this) : myType;
}
@Override
@@ -126,13 +105,11 @@ public class PsiFieldStubImpl extends StubBase<PsiField> implements PsiFieldStub
if (isDeprecated() || hasDeprecatedAnnotation()) {
builder.append("deprecated ");
}
-
if (isEnumConstant()) {
builder.append("enumconst ");
}
- TypeInfo type = getType(false); // this can be called from low-level code and we don't want resolve to mess with indexing
- builder.append(getName()).append(':').append(TypeInfo.createTypeText(type));
+ builder.append(myName).append(':').append(myType);
if (myInitializer != null) {
builder.append('=').append(myInitializer);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java
index f5c6a4bb5591..1463355455c2 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiMethodStubImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -37,8 +37,6 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
private final byte myFlags;
private final StringRef myName;
private StringRef myDefaultValueText;
- // todo[r.sh] drop this after transition period finished
- private boolean myHasExtMethodMark = false;
private static final int CONSTRUCTOR = 0x01;
private static final int VARARGS = 0x02;
@@ -46,24 +44,15 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
private static final int DEPRECATED = 0x08;
private static final int DEPRECATED_ANNOTATION = 0x10;
- public PsiMethodStubImpl(final StubElement parent,
- final StringRef name,
- final byte flags,
- final StringRef defaultValueText) {
+ public PsiMethodStubImpl(StubElement parent, StringRef name, byte flags, StringRef defaultValueText) {
super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD);
-
myFlags = flags;
myName = name;
myDefaultValueText = defaultValueText;
}
- public PsiMethodStubImpl(final StubElement parent,
- final StringRef name,
- final TypeInfo returnType,
- final byte flags,
- final StringRef defaultValueText) {
+ public PsiMethodStubImpl(StubElement parent, StringRef name, TypeInfo returnType, byte flags, StringRef defaultValueText) {
super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD);
-
myReturnType = returnType;
myFlags = flags;
myName = name;
@@ -74,14 +63,6 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
myReturnType = returnType;
}
- public void setExtensionMethodMark(boolean hasExtMethodMark) {
- myHasExtMethodMark = hasExtMethodMark;
- }
-
- public boolean hasExtensionMethodMark() {
- return myHasExtMethodMark;
- }
-
@Override
public boolean isConstructor() {
return (myFlags & CONSTRUCTOR) != 0;
@@ -109,8 +90,7 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
@Override
@NotNull
public TypeInfo getReturnTypeText(boolean doResolve) {
- if (!doResolve) return myReturnType;
- return PsiFieldStubImpl.addApplicableTypeAnnotationsFromChildModifierList(this, myReturnType);
+ return doResolve ? myReturnType.applyAnnotations(this) : myReturnType;
}
@Override
@@ -172,6 +152,7 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("PsiMethodStub[");
+
if (isConstructor()) {
builder.append("cons ");
}
@@ -185,9 +166,9 @@ public class PsiMethodStubImpl extends StubBase<PsiMethod> implements PsiMethodS
builder.append("deprecated ");
}
- builder.append(getName()).append(":").append(TypeInfo.createTypeText(getReturnTypeText(false)));
+ builder.append(myName).append(":").append(myReturnType);
- final String defaultValue = getDefaultValueText();
+ String defaultValue = getDefaultValueText();
if (defaultValue != null) {
builder.append(" default=").append(defaultValue);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java
index 2c66a4028e80..8c418e1a7386 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiParameterStubImpl.java
@@ -60,7 +60,7 @@ public class PsiParameterStubImpl extends StubBase<PsiParameter> implements PsiP
@Override
@NotNull
public TypeInfo getType(boolean doResolve) {
- return doResolve ? PsiFieldStubImpl.addApplicableTypeAnnotationsFromChildModifierList(this, myType) : myType;
+ return doResolve ? myType.applyAnnotations(this) : myType;
}
@Override
@@ -97,6 +97,6 @@ public class PsiParameterStubImpl extends StubBase<PsiParameter> implements PsiP
@Override
public String toString() {
- return "PsiParameterStub[" + myName + ':' + TypeInfo.createTypeText(getType(false)) + ']';
+ return "PsiParameterStub[" + myName + ':' + myType + ']';
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMethod.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMethod.java
index f9c6a570601c..6045a907e1e4 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMethod.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightMethod.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.light;
+import com.intellij.lang.Language;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.ItemPresentationProviders;
@@ -42,7 +43,14 @@ public class LightMethod extends LightElement implements PsiMethod {
private final PsiClass myContainingClass;
public LightMethod(@NotNull PsiManager manager, @NotNull PsiMethod method, @NotNull PsiClass containingClass) {
- super(manager, JavaLanguage.INSTANCE);
+ this(manager, method, containingClass, JavaLanguage.INSTANCE);
+ }
+
+ public LightMethod(@NotNull PsiManager manager,
+ @NotNull PsiMethod method,
+ @NotNull PsiClass containingClass,
+ @NotNull Language language) {
+ super(manager, language);
myMethod = method;
myContainingClass = containingClass;
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
index 192a57ade26c..a62915a9b013 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -37,7 +37,7 @@ import java.io.IOException;
* @author max
*/
public class JavaFileElementType extends ILightStubFileElementType<PsiJavaFileStub> {
- public static final int STUB_VERSION = 15;
+ public static final int STUB_VERSION = 16;
public JavaFileElementType() {
super("java.FILE", JavaLanguage.INSTANCE);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java
index 69fb266024db..6eafa4f31a77 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiClassReferenceType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -32,29 +32,27 @@ import java.util.List;
*/
public class PsiClassReferenceType extends PsiClassType {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiClassReferenceType");
+
private final PsiJavaCodeReferenceElement myReference;
- public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel languageLevel) {
- super(languageLevel, extractAnnosFromReference(reference));
+ public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel langLevel) {
+ this(reference, langLevel, collectAnnotations(reference));
+ }
+
+ public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel langLevel, @NotNull PsiAnnotation[] annotations) {
+ super(langLevel, annotations);
myReference = reference;
}
- private static PsiAnnotation[] extractAnnosFromReference(PsiJavaCodeReferenceElement reference) {
+ private static PsiAnnotation[] collectAnnotations(PsiJavaCodeReferenceElement reference) {
List<PsiAnnotation> result = null;
- for(PsiElement child = reference.getFirstChild(); child != null; child = child.getNextSibling()){
+ for (PsiElement child = reference.getFirstChild(); child != null; child = child.getNextSibling()) {
if (child instanceof PsiAnnotation) {
if (result == null) result = new SmartList<PsiAnnotation>();
result.add((PsiAnnotation)child);
}
}
-
- if (result == null) return PsiAnnotation.EMPTY_ARRAY;
- return result.toArray(new PsiAnnotation[result.size()]);
- }
-
- public PsiClassReferenceType(@NotNull PsiJavaCodeReferenceElement reference, LanguageLevel languageLevel, PsiAnnotation[] annotations) {
- super(languageLevel,annotations);
- myReference = reference;
+ return result == null ? PsiAnnotation.EMPTY_ARRAY : result.toArray(new PsiAnnotation[result.size()]);
}
@Override
@@ -84,7 +82,7 @@ public class PsiClassReferenceType extends PsiClassType {
@Override
public PsiClassType setLanguageLevel(@NotNull final LanguageLevel languageLevel) {
if (languageLevel.equals(myLanguageLevel)) return this;
- return new PsiClassReferenceType(myReference,languageLevel,getAnnotations());
+ return new PsiClassReferenceType(myReference, languageLevel, getAnnotations());
}
@Override
@@ -158,9 +156,9 @@ public class PsiClassReferenceType extends PsiClassType {
}
String qualifiedName = myReference.getQualifiedName();
String name = myReference.getReferenceName();
- if (name==null) name="";
+ if (name == null) name = "";
LightClassReference reference = new LightClassReference(myReference.getManager(), name, qualifiedName, myReference.getResolveScope());
- return new PsiClassReferenceType(reference, null,getAnnotations());
+ return new PsiClassReferenceType(reference, null, getAnnotations());
}
@Override
@@ -175,14 +173,14 @@ public class PsiClassReferenceType extends PsiClassType {
}
public PsiClassType createImmediateCopy() {
- final ClassResolveResult resolveResult = resolveGenerics();
- if (resolveResult.getElement() == null) return this;
- return new PsiImmediateClassType(resolveResult.getElement(), resolveResult.getSubstitutor());
+ ClassResolveResult resolveResult = resolveGenerics();
+ PsiClass element = resolveResult.getElement();
+ return element != null ? new PsiImmediateClassType(element, resolveResult.getSubstitutor()) : this;
}
@Override
public String getPresentableText() {
- return getAnnotationsTextPrefix() + PsiNameHelper.getPresentableText(myReference);
+ return getAnnotationsTextPrefix(false, false, true) + PsiNameHelper.getPresentableText(myReference);
}
@Override
@@ -192,7 +190,7 @@ public class PsiClassReferenceType extends PsiClassType {
@Override
public String getInternalCanonicalText() {
- return getAnnotationsTextPrefix() + getCanonicalText();
+ return getAnnotationsTextPrefix(true, false, true) + getCanonicalText();
}
@NotNull
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
index d815bab4235f..a5aed9804c40 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiImmediateClassType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -74,15 +75,18 @@ public class PsiImmediateClassType extends PsiClassType {
};
public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor) {
- this (aClass, substitutor, null);
+ this(aClass, substitutor, null, PsiAnnotation.EMPTY_ARRAY);
}
- public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, final LanguageLevel languageLevel) {
- this(aClass, substitutor,languageLevel, PsiAnnotation.EMPTY_ARRAY);
+ public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel) {
+ this(aClass, substitutor, languageLevel, PsiAnnotation.EMPTY_ARRAY);
}
- public PsiImmediateClassType(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor, LanguageLevel languageLevel, @NotNull PsiAnnotation[] annotations) {
- super(languageLevel,annotations);
+ public PsiImmediateClassType(@NotNull PsiClass aClass,
+ @NotNull PsiSubstitutor substitutor,
+ @Nullable LanguageLevel languageLevel,
+ @NotNull PsiAnnotation[] annotations) {
+ super(languageLevel, annotations);
myClass = aClass;
myManager = aClass.getManager();
mySubstitutor = substitutor;
@@ -131,7 +135,7 @@ public class PsiImmediateClassType extends PsiClassType {
@Override
public String getPresentableText() {
if (myPresentableText == null) {
- final StringBuilder buffer = new StringBuilder();
+ StringBuilder buffer = new StringBuilder();
buildText(myClass, mySubstitutor, buffer, false, false);
myPresentableText = buffer.toString();
}
@@ -142,7 +146,7 @@ public class PsiImmediateClassType extends PsiClassType {
public String getCanonicalText() {
if (myCanonicalText == null) {
assert mySubstitutor.isValid();
- final StringBuilder buffer = new StringBuilder();
+ StringBuilder buffer = new StringBuilder();
buildText(myClass, mySubstitutor, buffer, true, false);
myCanonicalText = buffer.toString();
}
@@ -152,7 +156,7 @@ public class PsiImmediateClassType extends PsiClassType {
@Override
public String getInternalCanonicalText() {
if (myInternalCanonicalText == null) {
- final StringBuilder buffer = new StringBuilder();
+ StringBuilder buffer = new StringBuilder();
buildText(myClass, mySubstitutor, buffer, true, true);
myInternalCanonicalText = buffer.toString();
}
@@ -173,6 +177,11 @@ public class PsiImmediateClassType extends PsiClassType {
}
return;
}
+
+ if (canonical == internal) {
+ buffer.append(getAnnotationsTextPrefix(internal, false, true));
+ }
+
PsiClass enclosingClass = null;
if (!aClass.hasModifierProperty(PsiModifier.STATIC)) {
final PsiElement parent = aClass.getParent();
@@ -180,7 +189,6 @@ public class PsiImmediateClassType extends PsiClassType {
enclosingClass = (PsiClass)parent;
}
}
- buffer.append(getAnnotationsTextPrefix());
if (enclosingClass != null) {
buildText(enclosingClass, substitutor, buffer, canonical, false);
buffer.append('.');
@@ -203,7 +211,7 @@ public class PsiImmediateClassType extends PsiClassType {
buffer.append(name);
}
- final PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
+ PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
if (typeParameters.length > 0) {
StringBuilder pineBuffer = new StringBuilder();
pineBuffer.append('<');
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
index 5cd2b0c2c810..e5cd665e9f57 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java
@@ -49,6 +49,8 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.List;
+
public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement implements PsiJavaCodeReferenceElement, SourceJavaCodeReference {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl");
@@ -193,56 +195,42 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
}
@Override
- public void deleteChildInternal(@NotNull final ASTNode child) {
+ public void deleteChildInternal(@NotNull ASTNode child) {
if (getChildRole(child) == ChildRole.QUALIFIER) {
- ASTNode dot = findChildByRole(ChildRole.DOT);
+ ASTNode dot = findChildByType(JavaTokenType.DOT, child);
assert dot != null : this;
deleteChildRange(child.getPsi(), dot.getPsi());
+
+ List<PsiAnnotation> annotations = PsiTreeUtil.getChildrenOfTypeAsList(this, PsiAnnotation.class);
+ setAnnotations(annotations);
+
+ return;
}
- else {
- super.deleteChildInternal(child);
- }
+
+ super.deleteChildInternal(child);
}
@Override
public final ASTNode findChildByRole(final int role) {
LOG.assertTrue(ChildRole.isUnique(role));
- switch (role) {
- default:
- return null;
- case ChildRole.REFERENCE_NAME:
- if (getLastChildNode().getElementType() == JavaTokenType.IDENTIFIER) {
- return getLastChildNode();
- }
- else {
- if (getLastChildNode().getElementType() == JavaElementType.REFERENCE_PARAMETER_LIST) {
- ASTNode current = getLastChildNode().getTreePrev();
- while (current != null && (current.getPsi() instanceof PsiWhiteSpace || current.getPsi() instanceof PsiComment)) {
- current = current.getTreePrev();
- }
- if (current != null && current.getElementType() == JavaTokenType.IDENTIFIER) {
- return current;
- }
- }
- return null;
- }
+ switch (role) {
+ case ChildRole.REFERENCE_NAME:
+ return TreeUtil.findChildBackward(this, JavaTokenType.IDENTIFIER);
- case ChildRole.REFERENCE_PARAMETER_LIST:
- if (getLastChildNode().getElementType() == JavaElementType.REFERENCE_PARAMETER_LIST) {
- return getLastChildNode();
+ case ChildRole.REFERENCE_PARAMETER_LIST: {
+ TreeElement lastChild = getLastChildNode();
+ return lastChild.getElementType() == JavaElementType.REFERENCE_PARAMETER_LIST ? lastChild : null;
}
- return null;
case ChildRole.QUALIFIER:
- if (getFirstChildNode().getElementType() == JavaElementType.JAVA_CODE_REFERENCE) {
- return getFirstChildNode();
- }
- return null;
+ return findChildByType(JavaElementType.JAVA_CODE_REFERENCE);
case ChildRole.DOT:
- return findChildByType(JavaTokenType.DOT);
+ return findChildByType(JavaTokenType.DOT);
}
+
+ return null;
}
@Override
@@ -380,7 +368,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
Project project = manager.getProject();
final ResolveCache resolveCache = ResolveCache.getInstance(project);
- final ResolveResult[] results = resolveCache.resolveWithCaching(this, OurGenericsResolver.INSTANCE, true, incompleteCode,file);
+ final ResolveResult[] results = resolveCache.resolveWithCaching(this, OurGenericsResolver.INSTANCE, true, incompleteCode, file);
return results.length == 0 ? JavaResolveResult.EMPTY_ARRAY : (JavaResolveResult[])results;
}
@@ -485,7 +473,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
}
}
- LOG.assertTrue(false, this);
+ LOG.error(this);
return JavaResolveResult.EMPTY_ARRAY;
}
@@ -552,38 +540,74 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
}
}
- private static IncorrectOperationException cannotBindError(final PsiElement element) {
- return new IncorrectOperationException("Cannot bind to "+element);
+ private static IncorrectOperationException cannotBindError(PsiElement element) {
+ return new IncorrectOperationException("Cannot bind to " + element);
}
- private PsiElement bindToClass(final PsiClass aClass) throws IncorrectOperationException {
+ private PsiElement bindToClass(PsiClass aClass) throws IncorrectOperationException {
String qName = aClass.getQualifiedName();
- final boolean preserveQualification = JavaCodeStyleSettingsFacade.getInstance(getProject()).useFQClassNames() && isFullyQualified();
- final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
+ boolean preserveQualification = JavaCodeStyleSettingsFacade.getInstance(getProject()).useFQClassNames() && isFullyQualified();
+ JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
if (qName == null) {
qName = aClass.getName();
- final PsiClass psiClass = facade.getResolveHelper().resolveReferencedClass(qName, this);
+ PsiClass psiClass = facade.getResolveHelper().resolveReferencedClass(qName, this);
if (!getManager().areElementsEquivalent(psiClass, aClass)) {
throw cannotBindError(aClass);
}
}
- else {
- if (facade.findClass(qName, getResolveScope()) == null && !preserveQualification) {
- return this;
- }
+ else if (facade.findClass(qName, getResolveScope()) == null && !preserveQualification) {
+ return this;
}
- final PsiReferenceParameterList parameterList = getParameterList();
- String text = parameterList == null ? qName : qName + parameterList.getText();
+ List<PsiAnnotation> annotations = getAnnotations();
+ String text = qName;
+ PsiReferenceParameterList parameterList = getParameterList();
+ if (parameterList != null) {
+ text += parameterList.getText();
+ }
PsiJavaCodeReferenceElement ref = facade.getParserFacade().createReferenceFromText(text, getParent());
getTreeParent().replaceChildInternal(this, (TreeElement)ref.getNode());
- if (!preserveQualification /*&& (TreeUtil.findParent(ref, ElementType.DOC_COMMENT) == null)*/) {
- final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(aClass.getProject());
+ ((PsiJavaCodeReferenceElementImpl)ref).setAnnotations(annotations);
+
+ if (!preserveQualification) {
+ JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(aClass.getProject());
ref = (PsiJavaCodeReferenceElement)codeStyleManager.shortenClassReferences(ref, JavaCodeStyleManager.UNCOMPLETE_CODE);
}
+
return ref;
}
+ private List<PsiAnnotation> getAnnotations() {
+ List<PsiAnnotation> annotations = PsiTreeUtil.getChildrenOfTypeAsList(this, PsiAnnotation.class);
+
+ if (!isQualified()) {
+ PsiModifierList modifierList = PsiImplUtil.findNeighbourModifierList(this);
+ if (modifierList != null) PsiImplUtil.addTypeUseAnnotations(modifierList, annotations);
+ }
+
+ return annotations;
+ }
+
+ private void setAnnotations(List<PsiAnnotation> annotations) {
+ if (annotations.isEmpty()) return;
+
+ PsiElement newParent = this;
+ PsiElement anchor = SourceTreeToPsiMap.treeElementToPsi(findChildByType(JavaTokenType.DOT));
+ if (anchor == null) {
+ PsiModifierList modifierList = PsiImplUtil.findNeighbourModifierList(this);
+ if (modifierList != null) {
+ newParent = modifierList;
+ }
+ }
+
+ for (PsiAnnotation annotation : annotations) {
+ if (annotation.getParent() != newParent) {
+ newParent.addAfter(annotation, anchor);
+ annotation.delete();
+ }
+ }
+ }
+
private boolean isFullyQualified() {
switch (getKind()) {
case CLASS_OR_PACKAGE_NAME_KIND:
@@ -712,7 +736,7 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme
@Override
public boolean isQualified() {
- return getChildRole(getFirstChildNode()) != ChildRole.REFERENCE_NAME;
+ return getQualifier() != null;
}
@Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java
index 9e8145fa25a3..7378569f99f0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiModifierListImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -28,17 +28,13 @@ import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.TreeElement;
-import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
@@ -134,12 +130,9 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
return false;
}
if (type == JavaTokenType.ABSTRACT_KEYWORD) {
- return !(getNode().findChildByType(JavaTokenType.DEFAULT_KEYWORD) != null || findExtensionMethodMarker((PsiMethod)parent) != null);
+ return getNode().findChildByType(JavaTokenType.DEFAULT_KEYWORD) == null;
}
}
- if (type == JavaTokenType.DEFAULT_KEYWORD && findExtensionMethodMarker((PsiMethod)parent) != null) {
- return true;
- }
}
else if (parent instanceof PsiField) {
if (parent instanceof PsiEnumConstant) {
@@ -179,16 +172,6 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
return getNode().findChildByType(type) != null;
}
- @Nullable
- public static PsiJavaToken findExtensionMethodMarker(@Nullable PsiMethod method) {
- // todo[r.sh] drop this after transition period finished
- if (method == null) return null;
- final PsiCodeBlock body = method.getBody();
- if (body == null) return null;
- final PsiElement previous = PsiTreeUtil.skipSiblingsBackward(body, PsiComment.class, PsiWhiteSpace.class);
- return previous instanceof PsiJavaToken && PsiUtil.isJavaToken(previous, JavaTokenType.DEFAULT_KEYWORD) ? (PsiJavaToken)previous : null;
- }
-
@Override
public boolean hasExplicitModifier(@NotNull String name) {
final CompositeElement tree = (CompositeElement)getNode();
@@ -234,7 +217,6 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
}
else if (parent instanceof PsiMethod && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) {
if (type == JavaTokenType.PUBLIC_KEYWORD || type == JavaTokenType.ABSTRACT_KEYWORD) return;
- if (type == JavaTokenType.DEFAULT_KEYWORD && findExtensionMethodMarker((PsiMethod)parent) != null) return;
}
else if (parent instanceof PsiClass && grandParent instanceof PsiClass && ((PsiClass)grandParent).isInterface()) {
if (type == JavaTokenType.PUBLIC_KEYWORD) return;
@@ -257,13 +239,6 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
if (child != null) {
SourceTreeToPsiMap.treeToPsiNotNull(child).delete();
}
-
- if (type == JavaTokenType.DEFAULT_KEYWORD && parent instanceof PsiMethod) {
- final PsiJavaToken marker = findExtensionMethodMarker((PsiMethod)parent);
- if (marker != null) {
- marker.delete();
- }
- }
}
}
@@ -283,11 +258,12 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
@Override
@NotNull
public PsiAnnotation[] getApplicableAnnotations() {
- final String[] fields = PsiAnnotationImpl.getApplicableElementTypeFields(this);
+ final PsiAnnotation.TargetType[] targets = PsiImplUtil.getTargetsForLocation(this);
List<PsiAnnotation> filtered = ContainerUtil.findAll(getAnnotations(), new Condition<PsiAnnotation>() {
@Override
public boolean value(PsiAnnotation annotation) {
- return PsiAnnotationImpl.isAnnotationApplicableTo(annotation, true, fields);
+ PsiAnnotation.TargetType target = PsiImplUtil.findApplicableTarget(annotation, targets);
+ return target != null && target != PsiAnnotation.TargetType.UNKNOWN;
}
});
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReferenceListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReferenceListImpl.java
index 2eff5acd41ed..2b8fcbb0a629 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReferenceListImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReferenceListImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -22,37 +22,38 @@ import com.intellij.psi.impl.java.stubs.PsiClassReferenceListStub;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
-public final class PsiReferenceListImpl extends JavaStubPsiElement<PsiClassReferenceListStub> implements PsiReferenceList {
+/**
+ * @author max
+ */
+public class PsiReferenceListImpl extends JavaStubPsiElement<PsiClassReferenceListStub> implements PsiReferenceList {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiReferenceListImpl");
- private static final TokenSet REFERENCE_BIT_SET = TokenSet.create(Constants.JAVA_CODE_REFERENCE);
- public PsiReferenceListImpl(final PsiClassReferenceListStub stub, final IStubElementType nodeType) {
+ public PsiReferenceListImpl(PsiClassReferenceListStub stub, IStubElementType nodeType) {
super(stub, nodeType);
}
- public PsiReferenceListImpl(final ASTNode node) {
+ public PsiReferenceListImpl(ASTNode node) {
super(node);
}
@Override
@NotNull
public PsiJavaCodeReferenceElement[] getReferenceElements() {
- return calcTreeElement().getChildrenAsPsiElements(REFERENCE_BIT_SET, PsiJavaCodeReferenceElement.ARRAY_FACTORY);
+ return calcTreeElement().getChildrenAsPsiElements(JavaElementType.JAVA_CODE_REFERENCE, PsiJavaCodeReferenceElement.ARRAY_FACTORY);
}
@Override
@NotNull
public PsiClassType[] getReferencedTypes() {
- final PsiClassReferenceListStub stub = getStub();
+ PsiClassReferenceListStub stub = getStub();
if (stub != null) {
return stub.getReferencedTypes();
}
- final PsiJavaCodeReferenceElement[] refs = getReferenceElements();
- final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
+ PsiJavaCodeReferenceElement[] refs = getReferenceElements();
+ PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
PsiClassType[] types = new PsiClassType[refs.length];
for (int i = 0; i < types.length; i++) {
types[i] = factory.createType(refs[i]);
@@ -63,24 +64,22 @@ public final class PsiReferenceListImpl extends JavaStubPsiElement<PsiClassRefer
@Override
public Role getRole() {
- final IElementType tt = getElementType();
-
- if (tt == JavaElementType.EXTENDS_LIST) {
+ IElementType type = getElementType();
+ if (type == JavaElementType.EXTENDS_LIST) {
return Role.EXTENDS_LIST;
}
- else if (tt == JavaElementType.IMPLEMENTS_LIST) {
+ else if (type == JavaElementType.IMPLEMENTS_LIST) {
return Role.IMPLEMENTS_LIST;
}
- else if (tt == JavaElementType.THROWS_LIST) {
+ else if (type == JavaElementType.THROWS_LIST) {
return Role.THROWS_LIST;
}
- else if (tt == JavaElementType.EXTENDS_BOUND_LIST) {
+ else if (type == JavaElementType.EXTENDS_BOUND_LIST) {
return Role.EXTENDS_BOUNDS_LIST;
}
- else {
- LOG.error("Unknown element type:" + tt);
- return null;
- }
+
+ LOG.error("Unknown element type:" + type);
+ return null;
}
@Override
@@ -94,6 +93,7 @@ public final class PsiReferenceListImpl extends JavaStubPsiElement<PsiClassRefer
}
public String toString() {
- return "PsiReferenceList";
+ return getElementType() == JavaElementType.EXTENDS_BOUND_LIST ? "PsiElement(EXTENDS_BOUND_LIST)"
+ : "PsiReferenceList"; // todo[r.sh] fix test data
}
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java
index b4086db18569..b8ba65024fa3 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiTypeElementImpl.java
@@ -23,7 +23,6 @@ import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.*;
-import com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
@@ -90,7 +89,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
while (element != null) {
IElementType elementType = element.getElementType();
if (element.getTreeNext() == null && ElementType.PRIMITIVE_TYPE_BIT_SET.contains(elementType)) {
- addTypeUseAnnotationsFromModifierList(getParent(), typeAnnotations);
+ PsiImplUtil.addTypeUseAnnotationsFromModifierList(getParent(), typeAnnotations);
final PsiAnnotation[] array = toAnnotationsArray(typeAnnotations);
cachedType = JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(element.getText(), array);
}
@@ -116,7 +115,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
}
}
else if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
- addTypeUseAnnotationsFromModifierList(getParent(), typeAnnotations);
+ PsiImplUtil.addTypeUseAnnotationsFromModifierList(getParent(), typeAnnotations);
final PsiAnnotation[] array = toAnnotationsArray(typeAnnotations);
final PsiJavaCodeReferenceElement reference = SourceTreeToPsiMap.treeToPsiNotNull(element);
cachedType = new PsiClassReferenceType(reference, null, array);
@@ -156,17 +155,6 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
return size == 0 ? PsiAnnotation.EMPTY_ARRAY : typeAnnotations.toArray(new PsiAnnotation[size]);
}
- public static void addTypeUseAnnotationsFromModifierList(PsiElement member, List<PsiAnnotation> typeAnnotations) {
- if (!(member instanceof PsiModifierListOwner)) return;
- PsiModifierList list = ((PsiModifierListOwner)member).getModifierList();
- PsiAnnotation[] gluedAnnotations = list == null ? PsiAnnotation.EMPTY_ARRAY : list.getAnnotations();
- for (PsiAnnotation anno : gluedAnnotations) {
- if (PsiAnnotationImpl.isAnnotationApplicableTo(anno, true, "TYPE_USE")) {
- typeAnnotations.add(anno);
- }
- }
- }
-
public PsiType getDetachedType(@NotNull PsiElement context) {
SoftReference<PsiType> cached = myCachedDetachedType;
PsiType type = cached == null ? null : cached.get();
@@ -313,7 +301,7 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
PsiAnnotation[] annotations = getAnnotations();
ArrayList<PsiAnnotation> list = new ArrayList<PsiAnnotation>(Arrays.asList(annotations));
- addTypeUseAnnotationsFromModifierList(getParent(), list);
+ PsiImplUtil.addTypeUseAnnotationsFromModifierList(getParent(), list);
return toAnnotationsArray(list);
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
index fae1b5252a07..ee65e9231c4a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
@@ -71,7 +71,7 @@ public class ProcessCandidateParameterTypeInferencePolicy extends DefaultParamet
protected PsiSubstitutor getSubstitutor(PsiCallExpression contextCall, PsiExpression[] expressions, int i, JavaResolveResult result) {
if (result instanceof MethodCandidateInfo) {
List<PsiExpression> leftArgs = getExpressions(expressions, i);
- return ((MethodCandidateInfo)result).inferTypeArguments(this, leftArgs.toArray(new PsiExpression[leftArgs.size()]));
+ return ((MethodCandidateInfo)result).inferSubstitutorFromArgs(this, leftArgs.toArray(new PsiExpression[leftArgs.size()]));
}
else {
return result.getSubstitutor();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java
index b61fb3d147f5..8c134391c77b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/ElementType.java
@@ -56,8 +56,7 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
ASSIGNMENT_EXPRESSION, NEW_EXPRESSION, ARRAY_ACCESS_EXPRESSION, ARRAY_INITIALIZER_EXPRESSION, INSTANCE_OF_EXPRESSION,
CLASS_OBJECT_ACCESS_EXPRESSION, METHOD_REF_EXPRESSION, LAMBDA_EXPRESSION, EMPTY_EXPRESSION);
- TokenSet ANNOTATION_MEMBER_VALUE_BIT_SET = TokenSet.orSet(EXPRESSION_BIT_SET,
- TokenSet.create(ANNOTATION, ANNOTATION_ARRAY_INITIALIZER));
+ 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,
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java
index 917458d55f92..50b2f5b45647 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaSharedImplUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -27,7 +27,12 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
public class JavaSharedImplUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.JavaSharedImplUtil");
@@ -35,7 +40,6 @@ public class JavaSharedImplUtil {
private JavaSharedImplUtil() { }
public static PsiType getType(@NotNull PsiTypeElement typeElement, @NotNull PsiElement anchor, @NotNull PsiElement context) {
- int cStyleArrayCount = countBrackets(anchor);
PsiType type;
if (typeElement instanceof PsiTypeElementImpl) {
type = ((PsiTypeElementImpl)typeElement).getDetachedType(context);
@@ -43,34 +47,61 @@ public class JavaSharedImplUtil {
else {
type = typeElement.getType();
}
- for (int i = 0; i < cStyleArrayCount; i++) {
- type = type.createArrayType();
+
+ List<PsiAnnotation[]> allAnnotations = collectAnnotations(anchor);
+ for (PsiAnnotation[] annotations : allAnnotations) {
+ type = type.createArrayType(annotations);
}
+
return type;
}
public static PsiType getTypeNoResolve(@NotNull PsiTypeElement typeElement, @NotNull PsiElement anchor, @NotNull PsiElement context) {
- int cStyleArrayCount = countBrackets(anchor);
PsiType type = typeElement.getTypeNoResolve(context);
- for (int i = 0; i < cStyleArrayCount; i++) {
- type = type.createArrayType();
+
+ List<PsiAnnotation[]> allAnnotations = collectAnnotations(anchor);
+ for (PsiAnnotation[] annotations : allAnnotations) {
+ type = type.createArrayType(annotations);
}
+
return type;
}
- private static int countBrackets(PsiElement anchor) {
- int cStyleArrayCount = 0;
- ASTNode name = SourceTreeToPsiMap.psiToTreeNotNull(anchor);
- for (ASTNode child = name.getTreeNext(); child != null; child = child.getTreeNext()) {
- IElementType i = child.getElementType();
+ private static List<PsiAnnotation[]> collectAnnotations(PsiElement anchor) {
+ List<PsiAnnotation[]> annotations = new SmartList<PsiAnnotation[]>();
+
+ List<PsiAnnotation> current = null;
+ for (PsiElement child = anchor.getNextSibling(); child != null; child = child.getNextSibling()) {
+ if (child instanceof PsiAnnotation) {
+ if (current == null) current = new SmartList<PsiAnnotation>();
+ current.add((PsiAnnotation)child);
+ continue;
+ }
+
+ IElementType i = child.getNode().getElementType();
if (i == JavaTokenType.LBRACKET) {
- cStyleArrayCount++;
+ annotations.add(ContainerUtil.toArray(current, PsiAnnotation.ARRAY_FACTORY));
+ current = null;
}
else if (i != JavaTokenType.RBRACKET && !ElementType.JAVA_COMMENT_OR_WHITESPACE_BIT_SET.contains(i)) {
break;
}
}
- return cStyleArrayCount;
+
+ return annotations;
+ }
+
+ @Nullable
+ public static PsiType findAnnotatedSubtype(@Nullable PsiType type, @NotNull PsiAnnotation annotation) {
+ while (type instanceof PsiArrayType) {
+ for (PsiAnnotation a : type.getAnnotations()) {
+ if (a == annotation) {
+ return type;
+ }
+ }
+ type = ((PsiArrayType)type).getComponentType();
+ }
+ return null;
}
public static void normalizeBrackets(PsiVariable variable) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java
index 5ddaaa191c93..b597d09c81a5 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiAnnotationImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -16,7 +16,6 @@
package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
-import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiImplUtil;
@@ -24,10 +23,10 @@ import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiAnnotationStub;
import com.intellij.psi.impl.meta.MetaRegistry;
import com.intellij.psi.impl.source.JavaStubPsiElement;
+import com.intellij.psi.impl.source.PsiClassReferenceType;
+import com.intellij.psi.impl.source.tree.JavaSharedImplUtil;
import com.intellij.psi.meta.PsiMetaData;
-import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
import com.intellij.util.PairFunction;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -37,8 +36,6 @@ import org.jetbrains.annotations.Nullable;
* @author ven
*/
public class PsiAnnotationImpl extends JavaStubPsiElement<PsiAnnotationStub> implements PsiAnnotation {
- private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiAnnotationImpl");
-
private static final PairFunction<Project, String, PsiAnnotation> ANNOTATION_CREATOR = new PairFunction<Project, String, PsiAnnotation>() {
@Override
public PsiAnnotation fun(Project project, String text) {
@@ -56,16 +53,12 @@ public class PsiAnnotationImpl extends JavaStubPsiElement<PsiAnnotationStub> imp
@Override
public PsiJavaCodeReferenceElement getNameReferenceElement() {
- final PsiAnnotationStub stub = getStub();
+ PsiAnnotationStub stub = getStub();
if (stub != null) {
return PsiTreeUtil.getRequiredChildOfType(stub.getPsiElement(), PsiJavaCodeReferenceElement.class);
}
- final Object result = PsiTreeUtil.getChildOfType(this, PsiJavaCodeReferenceElement.class);
- if (result != null && !(result instanceof PsiJavaCodeReferenceElement)) {
- throw new AssertionError("getChildOfType returned rubbish: " + result);
- }
- return (PsiJavaCodeReferenceElement)result;
+ return PsiTreeUtil.getChildOfType(this, PsiJavaCodeReferenceElement.class);
}
@Override
@@ -122,149 +115,33 @@ public class PsiAnnotationImpl extends JavaStubPsiElement<PsiAnnotationStub> imp
@Override
public PsiAnnotationOwner getOwner() {
PsiElement parent = getParent();
- if (!PsiUtil.isLanguageLevel8OrHigher(this)) {
- return parent instanceof PsiModifierList ? (PsiAnnotationOwner)parent : null;
- }
- if (parent instanceof PsiTypeElement) {
- return ((PsiTypeElement)parent).getOwner(this);
- }
- if (parent instanceof PsiTypeParameter) {
+ if (parent instanceof PsiAnnotationOwner) {
return (PsiAnnotationOwner)parent;
}
- PsiElement member = parent.getParent();
- String[] elementTypeFields = getApplicableElementTypeFields(member);
- if (elementTypeFields == null) return null;
- if (parent instanceof PsiAnnotationOwner
- && isAnnotationApplicableTo(this, true, elementTypeFields)) return (PsiAnnotationOwner)parent;
-
- PsiAnnotationOwner typeElement;
- if (member instanceof PsiVariable) {
- if (member instanceof PsiEnumConstant && parent instanceof PsiAnnotationOwner){
- return (PsiAnnotationOwner)parent;
- }
- typeElement = ((PsiVariable)member).getTypeElement();
- }
- else if (member instanceof PsiMethod && !((PsiMethod)member).isConstructor()) {
- typeElement = ((PsiMethod)member).getReturnTypeElement();
- }
- else if (parent instanceof PsiAnnotationOwner) {
- typeElement = (PsiAnnotationOwner)parent;
- }
- else {
- typeElement = null;
- }
- return typeElement;
- }
-
- public static boolean isAnnotationApplicableTo(PsiAnnotation annotation, boolean strict, String... elementTypeFields) {
- if (elementTypeFields == null) return true;
- PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
- if (nameRef == null) {
- return !strict;
- }
- PsiElement resolved = nameRef.resolve();
- if (!(resolved instanceof PsiClass) || !((PsiClass)resolved).isAnnotationType()) {
- return !strict;
- }
- PsiClass annotationType = (PsiClass)resolved;
- return isAnnotationApplicable(strict, annotationType, elementTypeFields, annotation.getResolveScope());
- }
-
- public static boolean isAnnotationApplicable(boolean strict,
- @NotNull PsiClass annotationType,
- @Nullable String[] elementTypeFields,
- GlobalSearchScope resolveScope) {
- if (elementTypeFields == null) {
- return !strict;
- }
- PsiAnnotation target = annotationType.getModifierList().findAnnotation(CommonClassNames.TARGET_ANNOTATION_FQ_NAME);
- if (target == null) {
- //todo hack: ambiguity in spec
- return !strict;
- //return !ArrayUtil.contains("TYPE_USE", elementTypeFields);
+ if (parent instanceof PsiNewExpression) {
+ return ((PsiNewExpression)parent).getOwner(this);
}
- PsiNameValuePair[] attributes = target.getParameterList().getAttributes();
- if (attributes.length == 0) {
- return !strict;
- }
- LOG.assertTrue(elementTypeFields.length > 0);
- PsiClass elementTypeClass =
- JavaPsiFacade.getInstance(annotationType.getProject()).findClass("java.lang.annotation.ElementType", resolveScope);
- if (elementTypeClass == null) {
- //todo hack
- return !strict;
- //return !ArrayUtil.contains("TYPE_USE", elementTypeFields);
+ if (parent instanceof PsiMethod) {
+ PsiType type = ((PsiMethod)parent).getReturnType();
+ return JavaSharedImplUtil.findAnnotatedSubtype(type, this);
}
- 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) {
- if (initializer instanceof PsiReference) {
- if (((PsiReference)initializer).isReferenceTo(field)) {
- return true;
- }
- }
- }
- }
- else if (value instanceof PsiReference) {
- if (((PsiReference)value).isReferenceTo(field)) {
- return true;
- }
+ if (parent instanceof PsiReferenceExpression) {
+ PsiElement ctx = parent.getParent();
+ if (ctx instanceof PsiMethodReferenceExpression) {
+ return new PsiClassReferenceType((PsiJavaCodeReferenceElement)parent, null);
}
}
- return false;
- }
-
- @Nullable
- public static String[] getApplicableElementTypeFields(PsiElement owner) {
- if (owner instanceof PsiClass) {
- PsiClass aClass = (PsiClass)owner;
- if (aClass.isAnnotationType()) {
- return new String[]{"ANNOTATION_TYPE", "TYPE"};
- }
- else if (aClass instanceof PsiTypeParameter) {
- return new String[]{"TYPE_PARAMETER"};
- }
- else {
- return new String[]{"TYPE"};
+ else if (parent instanceof PsiJavaCodeReferenceElement) {
+ PsiElement ctx = PsiTreeUtil.skipParentsOfType(parent, PsiJavaCodeReferenceElement.class);
+ if (ctx instanceof PsiReferenceList || ctx instanceof PsiNewExpression || ctx instanceof PsiTypeElement) {
+ return new PsiClassReferenceType((PsiJavaCodeReferenceElement)parent, null);
}
}
- if (owner instanceof PsiMethod) {
- if (((PsiMethod)owner).isConstructor()) {
- return new String[]{"CONSTRUCTOR"};
- }
- else {
- return new String[]{"METHOD"};
- }
- }
- if (owner instanceof PsiField) {
- return new String[]{"FIELD"};
- }
- if (owner instanceof PsiParameter) {
- return new String[]{"PARAMETER"};
- }
- if (owner instanceof PsiLocalVariable) {
- return new String[]{"LOCAL_VARIABLE"};
- }
- if (owner instanceof PsiPackageStatement) {
- return new String[]{"PACKAGE"};
- }
- if (owner instanceof PsiTypeElement) {
- return new String[]{"TYPE_USE"};
- }
return null;
}
-} \ No newline at end of file
+}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
index dc092a73346b..699e33476b48 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodCallExpressionImpl.java
@@ -17,6 +17,7 @@ package com.intellij.psi.impl.source.tree.java;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -194,7 +195,13 @@ public class PsiMethodCallExpressionImpl extends ExpressionPsiElement implements
if (is15OrHigher) {
final PsiSubstitutor substitutor = result.getSubstitutor();
PsiType substitutedReturnType = substitutor.substitute(ret);
- if (PsiUtil.isRawSubstitutor(method, substitutor) && ret.equals(substitutedReturnType)) return TypeConversionUtil.erasure(ret);
+ if (substitutedReturnType == null) return TypeConversionUtil.erasure(ret);
+ if (PsiUtil.isRawSubstitutor(method, substitutor)) {
+ final PsiType returnTypeErasure = TypeConversionUtil.erasure(ret);
+ if (Comparing.equal(TypeConversionUtil.erasure(substitutedReturnType), returnTypeErasure)) {
+ return returnTypeErasure;
+ }
+ }
PsiType lowerBound = PsiType.NULL;
if (substitutedReturnType instanceof PsiCapturedWildcardType) {
lowerBound = ((PsiCapturedWildcardType)substitutedReturnType).getLowerBound();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index 810e541cb387..e092c9e3178e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -267,6 +267,9 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
final PsiElement element = getReferenceNameElement();
final boolean isConstructor = element instanceof PsiKeyword && PsiKeyword.NEW.equals(element.getText());
if (element instanceof PsiIdentifier || isConstructor) {
+ if (isConstructor && (containingClass.isEnum() || containingClass.hasModifierProperty(PsiModifier.ABSTRACT))) {
+ return JavaResolveResult.EMPTY_ARRAY;
+ }
PsiType functionalInterfaceType = null;
final Map<PsiMethodReferenceExpression,PsiType> map = PsiMethodReferenceUtil.ourRefs.get();
if (map != null) {
@@ -289,9 +292,7 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
substitutor = LambdaUtil.inferFromReturnType(typeParameters, returnType, interfaceMethodReturnType, substitutor, languageLevel,
PsiMethodReferenceExpressionImpl.this.getProject());
- if (containingClass.getConstructors().length == 0 &&
- !containingClass.isEnum() &&
- !containingClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
+ if (containingClass.getConstructors().length == 0) {
ClassCandidateInfo candidateInfo = null;
if ((containingClass.getContainingClass() == null || !isLocatedInStaticContext(containingClass)) && signature.getParameterTypes().length == 0 ||
PsiMethodReferenceUtil.onArrayType(containingClass, signature)) {
@@ -358,9 +359,9 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
final PsiType[] types = method.getSignature(PsiUtil.isRawSubstitutor(method, substitutor) ? PsiSubstitutor.EMPTY : substitutor).getParameterTypes();
final PsiType[] rightTypes = signature.getParameterTypes();
if (types.length < rightTypes.length) {
- return PsiUtil.resolveGenericsClassInType(rightTypes[0]).getSubstitutor();
+ return getSubstitutor(rightTypes[0]);
} else if (types.length > rightTypes.length) {
- return PsiUtil.resolveGenericsClassInType(types[0]).getSubstitutor();
+ return getSubstitutor(types[0]);
}
for (int i = 0; i < rightTypes.length; i++) {
@@ -380,6 +381,20 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
languageLevel, PsiMethodReferenceExpressionImpl.this.getProject());
}
+ private PsiSubstitutor getSubstitutor(PsiType type) {
+ final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type);
+ PsiSubstitutor psiSubstitutor = resolveResult.getSubstitutor();
+ if (type instanceof PsiClassType) {
+ final PsiClass psiClass = resolveResult.getElement();
+ if (psiClass instanceof PsiTypeParameter) {
+ for (PsiClass aClass : psiClass.getSupers()) {
+ psiSubstitutor = psiSubstitutor.putAll(TypeConversionUtil.getSuperClassSubstitutor(aClass, (PsiClassType)type));
+ }
+ }
+ }
+ return psiSubstitutor;
+ }
+
private class MethodReferenceConflictResolver implements PsiConflictResolver {
private final PsiClass myContainingClass;
private final PsiSubstitutor mySubstitutor;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java
index 33d55ed03d56..dc8f0bb75f6e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiNewExpressionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,11 +30,10 @@ import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.List;
-
public class PsiNewExpressionImpl extends ExpressionPsiElement implements PsiNewExpression {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl");
@@ -43,39 +42,57 @@ public class PsiNewExpressionImpl extends ExpressionPsiElement implements PsiNew
}
@Override
- public PsiType getType(){
+ public PsiType getType() {
+ return doGetType(null);
+ }
+
+ @Override
+ public PsiType getOwner(@NotNull PsiAnnotation annotation) {
+ assert annotation.getParent() == this : annotation.getParent() + " != " + this;
+ return doGetType(annotation);
+ }
+
+ @Nullable
+ private PsiType doGetType(@Nullable PsiAnnotation stopAt) {
PsiType type = null;
- List<PsiAnnotation> annotations = new SmartList<PsiAnnotation>();
- for(ASTNode child = getFirstChildNode(); child != null; child = child.getTreeNext()){
+ SmartList<PsiAnnotation> annotations = new SmartList<PsiAnnotation>();
+ boolean stop = false;
+
+ for (ASTNode child = getFirstChildNode(); child != null; child = child.getTreeNext()) {
IElementType elementType = child.getElementType();
if (elementType == JavaElementType.ANNOTATION) {
- annotations.add((PsiAnnotation)child.getPsi());
- continue;
+ PsiAnnotation annotation = (PsiAnnotation)child.getPsi();
+ annotations.add(annotation);
+ if (annotation == stopAt) stop = true;
}
- if (elementType == JavaElementType.JAVA_CODE_REFERENCE){
- LOG.assertTrue(type == null);
- type = new PsiClassReferenceType((PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(child), null);
+ else if (elementType == JavaElementType.JAVA_CODE_REFERENCE) {
+ assert type == null : this;
+ type = new PsiClassReferenceType((PsiJavaCodeReferenceElement)child.getPsi(), null);
+ if (stop) return type;
}
- else if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(elementType)){
- LOG.assertTrue(type == null);
- PsiAnnotation[] annos = annotations.toArray(new PsiAnnotation[annotations.size()]);
- type = JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(child.getText(), annos);
+ else if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(elementType)) {
+ assert type == null : this;
+ PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
+ type = factory.createPrimitiveType(child.getText(), ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
+ if (stop) return type;
}
- else if (elementType == JavaTokenType.LBRACKET){
- LOG.assertTrue(type != null);
- PsiAnnotation[] annos = annotations.toArray(new PsiAnnotation[annotations.size()]);
-
- type = type.createArrayType(annos);
+ else if (elementType == JavaTokenType.LBRACKET) {
+ assert type != null : this;
+ type = type.createArrayType(ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
+ if (stop) return type;
}
- else if (elementType == JavaElementType.ANONYMOUS_CLASS){
- PsiAnnotation[] annos = annotations.toArray(new PsiAnnotation[annotations.size()]);
+ else if (elementType == JavaElementType.ANONYMOUS_CLASS) {
PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
- PsiClass aClass = (PsiClass)SourceTreeToPsiMap.treeElementToPsi(child);
+ PsiClass aClass = (PsiClass)child.getPsi();
PsiSubstitutor substitutor = aClass instanceof PsiTypeParameter ? PsiSubstitutor.EMPTY : factory.createRawSubstitutor(aClass);
- type = factory.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass),annos);
+ type = factory.createType(aClass, substitutor, PsiUtil.getLanguageLevel(aClass),
+ ContainerUtil.copyAndClear(annotations, PsiAnnotation.ARRAY_FACTORY, true));
+ if (stop) return type;
}
}
- return type;
+
+ // stop == true means annotation is misplaced
+ return stop ? null : type;
}
@Override
@@ -360,7 +377,7 @@ public class PsiNewExpressionImpl extends ExpressionPsiElement implements PsiNew
}
@Override
- public void accept(@NotNull PsiElementVisitor visitor){
+ public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
((JavaElementVisitor)visitor).visitNewExpression(this);
}
@@ -369,8 +386,7 @@ public class PsiNewExpressionImpl extends ExpressionPsiElement implements PsiNew
}
}
- public String toString(){
+ public String toString() {
return "PsiNewExpression:" + getText();
}
}
-
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java
deleted file mode 100644
index 8d03254b1cf2..000000000000
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiTypeParameterExtendsBoundsListImpl.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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.*;
-import com.intellij.psi.impl.java.stubs.PsiClassReferenceListStub;
-import com.intellij.psi.impl.source.Constants;
-import com.intellij.psi.impl.source.JavaStubPsiElement;
-import com.intellij.psi.stubs.IStubElementType;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author max
- */
-public class PsiTypeParameterExtendsBoundsListImpl extends JavaStubPsiElement<PsiClassReferenceListStub> implements PsiReferenceList {
- public PsiTypeParameterExtendsBoundsListImpl(final PsiClassReferenceListStub stub, final IStubElementType nodeType) {
- super(stub, nodeType);
- }
-
- public PsiTypeParameterExtendsBoundsListImpl(final ASTNode node) {
- super(node);
- }
-
- @Override
- @NotNull
- public PsiJavaCodeReferenceElement[] getReferenceElements() {
- return calcTreeElement().getChildrenAsPsiElements(Constants.JAVA_CODE_REFERENCE_BIT_SET, PsiJavaCodeReferenceElement.ARRAY_FACTORY);
- }
-
- @Override
- @NotNull
- public PsiClassType[] getReferencedTypes() {
- final PsiClassReferenceListStub stub = getStub();
- if (stub != null) return stub.getReferencedTypes();
-
- return createTypes(getReferenceElements());
- }
-
- @Override
- public Role getRole() {
- return Role.EXTENDS_BOUNDS_LIST;
- }
-
- private PsiClassType[] createTypes(final PsiJavaCodeReferenceElement[] refs) {
- final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
- PsiClassType[] types = new PsiClassType[refs.length];
- for (int i = 0; i < refs.length; i++) {
- types[i] = factory.createType(refs[i]);
- }
- return types;
- }
-
- @Override
- public void accept(@NotNull PsiElementVisitor visitor) {
- if (visitor instanceof JavaElementVisitor) {
- ((JavaElementVisitor)visitor).visitReferenceList(this);
- }
- else {
- visitor.visitElement(this);
- }
- }
-
- public String toString() {
- return "PsiElement(EXTENDS_BOUND_LIST)";
- }
-}
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
index b8141babaa3f..0eace78fea45 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
@@ -107,6 +107,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
final PsiMethod method = (PsiMethod)conflict.getElement();
if (method != null) {
final PsiParameter[] methodParameters = method.getParameterList().getParameters();
+ if (methodParameters.length == 0) continue;
final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
final PsiType paramType = param.getType();
if (!LambdaUtil.isAcceptable(lambdaExpression, conflict.getSubstitutor().substitute(paramType), true)) {