From 76878db4d6a820adc466b303bddde3e6f4285e99 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 19 Feb 2013 19:13:23 +0100 Subject: [PATCH 1/5] JB dictionary extended --- spellchecker/src/com/intellij/spellchecker/jetbrains.dic | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index 213b62f8225e..df370116615a 100644 --- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -94,6 +94,9 @@ deque dereference dereferences desc +deserializable +deserializer +deserializers dirs distinctrow django From ec59d21b4935351cae07092ab15ad7f00b0f9a50 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 19 Feb 2013 19:36:10 +0100 Subject: [PATCH 2/5] Test cleanup --- .../com/intellij/psi/JavaStubBuilderTest.java | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java b/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java index 0bead1f65548..5c91ddff01f4 100644 --- a/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/JavaStubBuilderTest.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. @@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.security.SecureRandom; +@SuppressWarnings("SpellCheckingInspection") public class JavaStubBuilderTest extends LightIdeaTestCase { private static final StubBuilder NEW_BUILDER = new JavaLightStubBuilder(); @@ -115,7 +116,7 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { "}\n" + "interface I {\n" + " void m1();\n" + - " void m2() default { }\n" + + " default void m2() { }\n" + "}", "PsiJavaFileStub []\n" + @@ -347,27 +348,10 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { " THROWS_LIST:PsiRefListStub[THROWS_LIST:]\n"); } - public void testAnnotationParameters() throws Exception { - doTest("@Deprecated(\"bar\")\n" + - "class Foo {\n" + - "}", - - "PsiJavaFileStub []\n" + - " IMPORT_LIST:PsiImportListStub\n" + - " CLASS:PsiClassStub[deprecatedA name=Foo fqn=Foo]\n" + - " MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" + - " ANNOTATION:PsiAnnotationStub[@Deprecated(\"bar\")]\n" + - " ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" + - " NAME_VALUE_PAIR:PsiNameValuePairStubImpl\n" + - " TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" + - " EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" + - " IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n"); - } - - public void testAnnotation() throws Exception { + public void testAnnotations() throws Exception { doTest("@Deprecated\n" + - "class Foo {\n" + - "}", + "@SuppressWarnings(\"UnusedDeclaration\")\n" + + "class Foo { }", "PsiJavaFileStub []\n" + " IMPORT_LIST:PsiImportListStub\n" + @@ -375,6 +359,9 @@ public class JavaStubBuilderTest extends LightIdeaTestCase { " MODIFIER_LIST:PsiModifierListStub[mask=4096]\n" + " ANNOTATION:PsiAnnotationStub[@Deprecated]\n" + " ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" + + " ANNOTATION:PsiAnnotationStub[@SuppressWarnings(\"UnusedDeclaration\")]\n" + + " ANNOTATION_PARAMETER_LIST:PsiAnnotationParameterListStubImpl\n" + + " NAME_VALUE_PAIR:PsiNameValuePairStubImpl\n" + " TYPE_PARAMETER_LIST:PsiTypeParameterListStub\n" + " EXTENDS_LIST:PsiRefListStub[EXTENDS_LIST:]\n" + " IMPLEMENTS_LIST:PsiRefListStub[IMPLEMENTS_LIST:]\n"); From 5dd63254274ef7b12814b5d78d7419952b1937e5 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 19 Feb 2013 20:24:22 +0100 Subject: [PATCH 3/5] Cleanup (formatting, constants) --- .../com/intellij/psi/impl/cache/TypeInfo.java | 122 +++++++++--------- 1 file changed, 63 insertions(+), 59 deletions(-) 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 9e6d0eca8999..c575fda495b7 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 @@ -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. @@ -43,6 +43,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static com.intellij.util.BitUtil.isSet; + /** * @author max */ @@ -52,14 +54,9 @@ public class TypeInfo { private static final TIntObjectHashMap ourIndexFrequentType = new TIntObjectHashMap(); private static final TObjectIntHashMap ourFrequentTypeIndex = new TObjectIntHashMap(); - public final StringRef text; - public final byte arrayCount; - public final boolean isEllipsis; - private final List myAnnotationStubs; - private static void registerFrequentType(String typeText) { int index = ourFrequentTypeIndex.size() + 1; - assert index < 15; // 0xf is reserved + assert index > 0 && index < 15 : "reserved: " + index + " (" + typeText + ")"; ourFrequentTypeIndex.put(typeText, index); ourIndexFrequentType.put(index, typeText); } @@ -78,9 +75,22 @@ public class TypeInfo { registerFrequentType("Object"); registerFrequentType(CommonClassNames.JAVA_LANG_OBJECT); registerFrequentType("String"); - registerFrequentType("java.lang.String"); + registerFrequentType(CommonClassNames.JAVA_LANG_STRING); } + 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 TypeInfo NULL = new TypeInfo(null, (byte)0, false, Collections.emptyList()); + + public final StringRef text; + public final byte arrayCount; + public final boolean isEllipsis; + private final List myAnnotationStubs; + public TypeInfo(StringRef text, byte arrayCount, boolean ellipsis, @NotNull List annotationStubs) { this.text = text; this.arrayCount = arrayCount; @@ -101,8 +111,8 @@ public class TypeInfo { } @NotNull - public static TypeInfo create(final LighterAST tree, final LighterASTNode element, final StubElement parentStub) { - final String text; + public static TypeInfo create(@NotNull LighterAST tree, @NotNull LighterASTNode element, StubElement parentStub) { + String text; int arrayCount = 0; boolean isEllipsis = false; @@ -113,7 +123,7 @@ public class TypeInfo { LighterASTNode typeElement = null; for (final LighterASTNode child : tree.getChildren(element)) { - final IElementType type = child.getTokenType(); + IElementType type = child.getTokenType(); if (type == JavaElementType.TYPE) { typeElement = child; } @@ -123,8 +133,10 @@ public class TypeInfo { } if (typeElement == null && element.getTokenType() == JavaElementType.FIELD) { - final List fields = LightTreeUtil.getChildrenOfType(tree, tree.getParent(element), JavaElementType.FIELD); - final int idx = fields.indexOf(element); + LighterASTNode parent = tree.getParent(element); + assert parent != null : element; + List fields = LightTreeUtil.getChildrenOfType(tree, parent, JavaElementType.FIELD); + int idx = fields.indexOf(element); for (int i = idx - 1; i >= 0 && typeElement == null; i--) { // int i, j typeElement = LightTreeUtil.firstChildOfType(tree, fields.get(i), JavaElementType.TYPE); } @@ -135,7 +147,7 @@ public class TypeInfo { isEllipsis = (LightTreeUtil.firstChildOfType(tree, typeElement, JavaTokenType.ELLIPSIS) != null); while (true) { - final LighterASTNode nested = LightTreeUtil.firstChildOfType(tree, typeElement, JavaElementType.TYPE); + LighterASTNode nested = LightTreeUtil.firstChildOfType(tree, typeElement, JavaElementType.TYPE); if (nested == null) break; typeElement = nested; arrayCount++; // Java-style array @@ -144,7 +156,7 @@ public class TypeInfo { text = LightTreeUtil.toFilteredString(tree, typeElement, null); } - final List annotations = Collections.emptyList(); // todo[r.sh] JDK 8 type annotations + List annotations = Collections.emptyList(); // todo[r.sh] JDK 8 type annotations return new TypeInfo(StringRef.fromString(text), (byte)arrayCount, isEllipsis, annotations); } @@ -175,35 +187,25 @@ public class TypeInfo { return fromString(typeText, isEllipsis); } - private static final TypeInfo NULL = new TypeInfo(null, (byte)0, false, Collections.emptyList()); - @NotNull - public static TypeInfo readTYPE(StubInputStream record, StubElement parentStub) throws IOException { - final int flags = 0xFF & record.readByte(); + public static TypeInfo readTYPE(@NotNull StubInputStream record, StubElement parentStub) throws IOException { + int flags = 0xFF & record.readByte(); if (flags == NULL_FLAGS) { return NULL; } - // flags bits - // ZeroPad:1 IsEllipsis:1 ArrayCountPresent:1 AnnotationsArePresent:1 FrequentIndex:4 + 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); - final int frequentIndex = 0xF & flags; + StringRef text = frequentIndex == 0 ? record.readName() : StringRef.fromString(ourIndexFrequentType.get(frequentIndex)); - byte arrayCount = (flags & 0x20) != 0 ? record.readByte() : 0; - boolean isEllipsis = (flags & 0x40) != 0; - StringRef text; - if (frequentIndex == 0) { - text = record.readName(); - } - else { - text = StringRef.fromString(ourIndexFrequentType.get(frequentIndex)); - } - boolean annotationsArePresent = (flags & 0x10) != 0; List annotationStubs; - if (annotationsArePresent) { + if (hasAnnotations) { int size = 0xFF & record.readByte(); annotationStubs = new ArrayList(size); - for (int i =0; i annotations = typeInfo.myAnnotationStubs; - boolean annotationsArePresent = !annotations.isEmpty(); - int flags = ((isEllipsis ? 1 : 0) << 6) | - ((arrayCount == 0 ? 0 : 1) << 5) | - ((annotationsArePresent ? 1 : 0)<<4) | - frequentIndex; + boolean hasAnnotations = !annotations.isEmpty(); + int flags = (hasEllipsis ? HAS_ELLIPSIS : 0) | + (arrayCount != 0 ? HAS_ARRAY_COUNT : 0) | + (hasAnnotations ? HAS_ANNOTATIONS : 0) | + frequentIndex; + dataStream.writeByte(flags); if (arrayCount != 0) { dataStream.writeByte(arrayCount); @@ -244,7 +241,7 @@ public class TypeInfo { if (frequentIndex == 0) { dataStream.writeName(text); } - if (annotationsArePresent) { + if (hasAnnotations) { LOG.assertTrue(annotations.size() < 256, annotations.size()); dataStream.writeByte(annotations.size()); for (PsiAnnotationStub annotation : annotations) { @@ -255,18 +252,25 @@ public class TypeInfo { @Nullable public static String createTypeText(@NotNull TypeInfo typeInfo) { - if (typeInfo == NULL) return null; - if (typeInfo.text == null) return null; - if (typeInfo.arrayCount == 0 && typeInfo.myAnnotationStubs.isEmpty()) return typeInfo.text.getString(); + if (typeInfo == NULL || typeInfo.text == null) { + return null; + } + if (typeInfo.arrayCount == 0 && typeInfo.myAnnotationStubs.isEmpty()) { + return typeInfo.text.getString(); + } + + StringBuilder buf = new StringBuilder(); - String text = typeInfo.text.getString(); - StringBuilder buf = new StringBuilder(text.length()); for (PsiAnnotationStub stub : typeInfo.myAnnotationStubs) { buf.append(stub.getText()).append(" "); } - buf.append(text); - final int arrayCount = typeInfo.isEllipsis ? typeInfo.arrayCount - 1 : typeInfo.arrayCount; - for (int i = 0; i < arrayCount; i++) buf.append("[]"); + + buf.append(typeInfo.text.getString()); + + int arrayCount = typeInfo.isEllipsis ? typeInfo.arrayCount - 1 : typeInfo.arrayCount; + for (int i = 0; i < arrayCount; i++) { + buf.append("[]"); + } if (typeInfo.isEllipsis) { buf.append("..."); } @@ -284,4 +288,4 @@ public class TypeInfo { String name = PsiNameHelper.getShortClassName(text.getString()); return arrayCount > 0 ? name + StringUtil.repeat("[]", arrayCount) : name; } -} \ No newline at end of file +} From a7474d109be4857409b5fa1feff662571d062ef3 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 19 Feb 2013 20:56:01 +0100 Subject: [PATCH 4/5] Nullability --- .../intellij/psi/impl/cache/RecordUtil.java | 5 ++-- .../psi/impl/source/tree/LightTreeUtil.java | 23 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) 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 27541048658a..3e83c7a42329 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 @@ -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. @@ -146,6 +146,7 @@ public class RecordUtil { return packed; } + @NotNull public static String intern(@NotNull CharTable table, @NotNull LighterASTNode node) { assert node instanceof LighterASTTokenNode : node; return table.intern(((LighterASTTokenNode)node).getText()).toString(); @@ -160,4 +161,4 @@ public class RecordUtil { int mask = ((PsiModifierListStub)type).getModifiersMask(); return ModifierFlags.hasModifierProperty(PsiModifier.STATIC, mask) && !ModifierFlags.hasModifierProperty(PsiModifier.PRIVATE, mask); } -} \ No newline at end of file +} diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java index f0fc0366766a..a42c0bc4328f 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 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,15 +28,14 @@ import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; - public class LightTreeUtil { private LightTreeUtil() { } @Nullable - public static LighterASTNode firstChildOfType(final LighterAST tree, final LighterASTNode node, final IElementType type) { + public static LighterASTNode firstChildOfType(@NotNull LighterAST tree, @NotNull LighterASTNode node, @NotNull IElementType type) { List children = tree.getChildren(node); for (int i = 0, size = children.size(); i < size; ++i) { - final LighterASTNode child = children.get(i); + LighterASTNode child = children.get(i); if (child.getTokenType() == type) return child; } @@ -44,19 +43,19 @@ public class LightTreeUtil { } @NotNull - public static LighterASTNode requiredChildOfType(final LighterAST tree, final LighterASTNode node, final IElementType type) { - final LighterASTNode child = firstChildOfType(tree, node, type); + public static LighterASTNode requiredChildOfType(@NotNull LighterAST tree, @NotNull LighterASTNode node, @NotNull IElementType type) { + LighterASTNode child = firstChildOfType(tree, node, type); assert child != null : "Required child " + type + " not found in " + node.getTokenType() + ": " + tree.getChildren(node); return child; } @NotNull - public static List getChildrenOfType(final LighterAST tree, final LighterASTNode node, final IElementType type) { + public static List getChildrenOfType(@NotNull LighterAST tree, @NotNull LighterASTNode node, @NotNull IElementType type) { List result = null; List children = tree.getChildren(node); for (int i = 0, size = children.size(); i < size; ++i) { - final LighterASTNode child = children.get(i); + LighterASTNode child = children.get(i); if (child.getTokenType() == type) { if (result == null) result = new SmartList(); result.add(child); @@ -66,13 +65,13 @@ public class LightTreeUtil { return result != null ? result: Collections.emptyList(); } - public static String toFilteredString(final LighterAST tree, final LighterASTNode node, @Nullable final TokenSet skipTypes) { - final StringBuilder buffer = new StringBuilder(node.getEndOffset() - node.getStartOffset()); + public static String toFilteredString(@NotNull LighterAST tree, @NotNull LighterASTNode node, @Nullable TokenSet skipTypes) { + StringBuilder buffer = new StringBuilder(node.getEndOffset() - node.getStartOffset()); toBuffer(tree, node, buffer, skipTypes); return buffer.toString(); } - private static void toBuffer(final LighterAST tree, final LighterASTNode node, final StringBuilder buffer, @Nullable final TokenSet skipTypes) { + private static void toBuffer(@NotNull LighterAST tree, @NotNull LighterASTNode node, @NotNull StringBuilder buffer, @Nullable TokenSet skipTypes) { if (skipTypes != null && skipTypes.contains(node.getTokenType())) return; if (node instanceof LighterASTTokenNode) { @@ -90,4 +89,4 @@ public class LightTreeUtil { toBuffer(tree, children.get(i), buffer, skipTypes); } } -} \ No newline at end of file +} From caf9bd61ffc8109bd6778e9cc3f58253e9a045c2 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 19 Feb 2013 21:02:46 +0100 Subject: [PATCH 5/5] Java type annotations: receiver parameter PSI --- .../intellij/psi/PsiReceiverParameter.java | 24 +++++++ .../java/stubs/JavaParameterElementType.java | 43 ++++++------ .../impl/java/stubs/JavaStubElementTypes.java | 21 +++++- .../psi/impl/java/stubs/PsiParameterStub.java | 20 ++++-- .../impl/java/stubs/SourceStubPsiFactory.java | 4 +- .../java/stubs/impl/PsiParameterStubImpl.java | 23 ++++--- .../psi/impl/source/PsiParameterImpl.java | 67 +++++++++++++------ .../impl/source/PsiReceiverParameterImpl.java | 37 ++++++++++ .../psi/impl/source/tree/JavaElementType.java | 3 +- .../source/tree/java/ParameterElement.java | 42 ++++++------ .../psi/impl/source/tree/LightTreeUtil.java | 18 +++++ 11 files changed, 213 insertions(+), 89 deletions(-) create mode 100644 java/java-psi-api/src/com/intellij/psi/PsiReceiverParameter.java create mode 100644 java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReceiverParameterImpl.java diff --git a/java/java-psi-api/src/com/intellij/psi/PsiReceiverParameter.java b/java/java-psi-api/src/com/intellij/psi/PsiReceiverParameter.java new file mode 100644 index 000000000000..f3851a9fe54e --- /dev/null +++ b/java/java-psi-api/src/com/intellij/psi/PsiReceiverParameter.java @@ -0,0 +1,24 @@ +/* + * 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. + * 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; + +/** + * Represents a receiver parameter of a Java method (Java 8). + * + * @since 12.1 + */ +public interface PsiReceiverParameter extends PsiParameter { +} 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 a38b94c3179c..f9ebdd67b767 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 @@ -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. @@ -24,12 +24,14 @@ import com.intellij.psi.impl.cache.RecordUtil; import com.intellij.psi.impl.cache.TypeInfo; import com.intellij.psi.impl.java.stubs.impl.PsiParameterStubImpl; import com.intellij.psi.impl.source.PsiParameterImpl; +import com.intellij.psi.impl.source.PsiReceiverParameterImpl; +import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.impl.source.tree.LightTreeUtil; -import com.intellij.psi.impl.source.tree.java.ParameterElement; import com.intellij.psi.stubs.IndexSink; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.stubs.StubInputStream; import com.intellij.psi.stubs.StubOutputStream; +import com.intellij.psi.tree.TokenSet; import com.intellij.util.io.StringRef; import org.jetbrains.annotations.NotNull; @@ -38,15 +40,11 @@ import java.io.IOException; /** * @author max */ -public class JavaParameterElementType extends JavaStubElementType { - public JavaParameterElementType() { - super("PARAMETER"); - } +public abstract class JavaParameterElementType extends JavaStubElementType { + public static final TokenSet ID_TYPES = TokenSet.create(JavaTokenType.IDENTIFIER, JavaTokenType.THIS_KEYWORD); - @NotNull - @Override - public ASTNode createCompositeNode() { - return new ParameterElement(); + public JavaParameterElementType(@NotNull String id) { + super(id); } @Override @@ -55,36 +53,35 @@ public class JavaParameterElementType extends JavaStubElementType { + @NotNull + @Override + String getName(); + boolean isParameterTypeEllipsis(); - @NotNull TypeInfo getType(boolean doResolve); + + @NotNull + TypeInfo getType(boolean doResolve); + PsiModifierListStub getModList(); + + boolean isReceiver(); } \ No newline at end of file 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 1b5a5f763bfd..d64f7afff81e 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 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. @@ -86,7 +86,7 @@ public class SourceStubPsiFactory extends StubPsiFactory { @Override public PsiParameter createParameter(PsiParameterStub stub) { - return new PsiParameterImpl(stub); + return stub.isReceiver() ? new PsiReceiverParameterImpl(stub) : new PsiParameterImpl(stub); } @Override 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 9e732a209201..2c66a4028e80 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 @@ -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.java.stubs.impl; +import com.intellij.psi.PsiKeyword; import com.intellij.psi.PsiParameter; import com.intellij.psi.impl.cache.TypeInfo; import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; @@ -35,11 +36,11 @@ public class PsiParameterStubImpl extends StubBase implements PsiP private final TypeInfo myType; private final boolean myIsEllipsis; - public PsiParameterStubImpl(final StubElement parent, final String name, @NotNull TypeInfo type, final boolean isEllipsis) { + public PsiParameterStubImpl(StubElement parent, @NotNull String name, @NotNull TypeInfo type, boolean isEllipsis) { this(parent, StringRef.fromString(name), type, isEllipsis); } - public PsiParameterStubImpl(final StubElement parent, final StringRef name, @NotNull TypeInfo type, final boolean isEllipsis) { + public PsiParameterStubImpl(StubElement parent, @NotNull StringRef name, @NotNull TypeInfo type, boolean isEllipsis) { super(parent, JavaStubElementTypes.PARAMETER); myName = name; myType = type; @@ -51,11 +52,15 @@ public class PsiParameterStubImpl extends StubBase implements PsiP return myIsEllipsis; } + @Override + public boolean isReceiver() { + return PsiKeyword.THIS.equals(getName()); + } + @Override @NotNull public TypeInfo getType(boolean doResolve) { - if (!doResolve) return myType; - return PsiFieldStubImpl.addApplicableTypeAnnotationsFromChildModifierList(this, myType); + return doResolve ? PsiFieldStubImpl.addApplicableTypeAnnotationsFromChildModifierList(this, myType) : myType; } @Override @@ -68,6 +73,7 @@ public class PsiParameterStubImpl extends StubBase implements PsiP return null; } + @NotNull @Override public String getName() { return StringRef.toString(myName); @@ -91,11 +97,6 @@ public class PsiParameterStubImpl extends StubBase implements PsiP @Override public String toString() { - StringBuilder builder = new StringBuilder(); - builder. - append("PsiParameterStub["). - append(myName).append(':').append(TypeInfo.createTypeText(getType(false))). - append(']'); - return builder.toString(); + return "PsiParameterStub[" + myName + ':' + TypeInfo.createTypeText(getType(false)) + ']'; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java index 89717007ca90..446f4ce06f6d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiParameterImpl.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. @@ -26,11 +26,12 @@ import com.intellij.psi.impl.PsiImplUtil; import com.intellij.psi.impl.cache.TypeInfo; import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; import com.intellij.psi.impl.java.stubs.PsiParameterStub; -import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.impl.source.tree.JavaSharedImplUtil; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.SearchScope; +import com.intellij.psi.stubs.IStubElementType; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.ui.RowIcon; import com.intellij.util.IncorrectOperationException; import com.intellij.util.PatchedSoftReference; @@ -42,10 +43,15 @@ import java.util.Arrays; public class PsiParameterImpl extends JavaStubPsiElement implements PsiParameter { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiParameterImpl"); + private volatile PatchedSoftReference myCachedType = null; public PsiParameterImpl(@NotNull PsiParameterStub stub) { - super(stub, JavaStubElementTypes.PARAMETER); + this(stub, JavaStubElementTypes.PARAMETER); + } + + protected PsiParameterImpl(@NotNull PsiParameterStub stub, @NotNull IStubElementType type) { + super(stub, type); } public PsiParameterImpl(@NotNull ASTNode node) { @@ -69,23 +75,34 @@ public class PsiParameterImpl extends JavaStubPsiElement imple @Override @NotNull public final String getName() { - final PsiParameterStub stub = getStub(); + PsiParameterStub stub = getStub(); if (stub != null) { return stub.getName(); } - return getNameIdentifier().getText(); + + return getParameterIdentifier().getText(); } @Override - public PsiElement setName(@NotNull String name) throws IncorrectOperationException { - PsiImplUtil.setName(getNameIdentifier(), name); + public final PsiElement setName(@NotNull String name) throws IncorrectOperationException { + if (this instanceof PsiReceiverParameter) { + throw new IncorrectOperationException("Cannot rename receiver parameter"); + } + + PsiImplUtil.setName(getParameterIdentifier(), name); return this; } @Override - @NotNull public final PsiIdentifier getNameIdentifier() { - return (PsiIdentifier)getNode().findChildByRoleAsPsiElement(ChildRole.NAME); + return PsiTreeUtil.getChildOfType(this, PsiIdentifier.class); + } + + @NotNull + private PsiElement getParameterIdentifier() { + PsiJavaToken identifier = PsiTreeUtil.getChildOfAnyType(this, PsiIdentifier.class, PsiKeyword.class); + assert identifier != null : this; + return identifier; } @Override @@ -97,7 +114,7 @@ public class PsiParameterImpl extends JavaStubPsiElement imple @Override @NotNull public PsiType getType() { - final PsiParameterStub stub = getStub(); + PsiParameterStub stub = getStub(); if (stub != null) { PatchedSoftReference cachedType = myCachedType; if (cachedType != null) { @@ -106,8 +123,9 @@ public class PsiParameterImpl extends JavaStubPsiElement imple } String typeText = TypeInfo.createTypeText(stub.getType(true)); + assert typeText != null : stub; try { - final PsiType type = JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(typeText, this); + PsiType type = JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(typeText, this); myCachedType = new PatchedSoftReference(type); return type; } @@ -119,19 +137,22 @@ public class PsiParameterImpl extends JavaStubPsiElement imple myCachedType = null; - final PsiTypeElement typeElement = getTypeElement(); - if (typeElement == null && isLambdaParameter()) { + PsiTypeElement typeElement = getTypeElement(); + if (typeElement == null) { + assert isLambdaParameter() : this; return LambdaUtil.getLambdaParameterType(this); } - - return JavaSharedImplUtil.getType(typeElement, getNameIdentifier(), this); + else { + return JavaSharedImplUtil.getType(typeElement, getParameterIdentifier(), this); + } } @Override public PsiType getTypeNoResolve() { - final PsiParameterStub stub = getStub(); + PsiParameterStub stub = getStub(); if (stub != null) { String typeText = TypeInfo.createTypeText(stub.getType(false)); + assert typeText != null : stub; try { return JavaPsiFacade.getInstance(getProject()).getParserFacade().createTypeFromText(typeText, this); } @@ -142,11 +163,13 @@ public class PsiParameterImpl extends JavaStubPsiElement imple } final PsiTypeElement typeElement = getTypeElement(); - if (typeElement == null && isLambdaParameter()) { + if (typeElement == null) { + assert isLambdaParameter() : this; return new PsiLambdaParameterType(this); } - - return JavaSharedImplUtil.getTypeNoResolve(typeElement, getNameIdentifier(), this); + else { + return JavaSharedImplUtil.getTypeNoResolve(typeElement, getParameterIdentifier(), this); + } } private boolean isLambdaParameter() { @@ -156,13 +179,15 @@ public class PsiParameterImpl extends JavaStubPsiElement imple @Override public PsiTypeElement getTypeElement() { - return (PsiTypeElement)getNode().findChildByRoleAsPsiElement(ChildRole.TYPE); + return PsiTreeUtil.getChildOfType(this, PsiTypeElement.class); } @Override @NotNull public PsiModifierList getModifierList() { - return getStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST); + PsiModifierList modifierList = getStubOrPsiChild(JavaStubElementTypes.MODIFIER_LIST); + assert modifierList != null : this; + return modifierList; } @Override diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReceiverParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReceiverParameterImpl.java new file mode 100644 index 000000000000..9bf940bf7f7d --- /dev/null +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiReceiverParameterImpl.java @@ -0,0 +1,37 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.source; + +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiReceiverParameter; +import com.intellij.psi.impl.java.stubs.JavaStubElementTypes; +import com.intellij.psi.impl.java.stubs.PsiParameterStub; +import org.jetbrains.annotations.NotNull; + +public class PsiReceiverParameterImpl extends PsiParameterImpl implements PsiReceiverParameter { + public PsiReceiverParameterImpl(@NotNull PsiParameterStub stub) { + super(stub, JavaStubElementTypes.RECEIVER_PARAMETER); + } + + public PsiReceiverParameterImpl(@NotNull ASTNode node) { + super(node); + } + + @Override + public String toString() { + return "PsiReceiverParameter"; + } +} diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java index a24e5f5f8b05..3ffd29fc03bc 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/JavaElementType.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. @@ -76,6 +76,7 @@ public interface JavaElementType { IElementType ANNOTATION_METHOD = JavaStubElementTypes.ANNOTATION_METHOD; IElementType CLASS_INITIALIZER = JavaStubElementTypes.CLASS_INITIALIZER; IElementType PARAMETER = JavaStubElementTypes.PARAMETER; + IElementType RECEIVER_PARAMETER = JavaStubElementTypes.RECEIVER_PARAMETER; IElementType PARAMETER_LIST = JavaStubElementTypes.PARAMETER_LIST; IElementType EXTENDS_BOUND_LIST = JavaStubElementTypes.EXTENDS_BOUND_LIST; IElementType THROWS_LIST = JavaStubElementTypes.THROWS_LIST; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterElement.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterElement.java index 0d3aeac52c66..7a3d42fd9b48 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterElement.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/ParameterElement.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,50 +18,49 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.JavaTokenType; +import com.intellij.psi.impl.java.stubs.JavaParameterElementType; import com.intellij.psi.impl.source.tree.ChildRole; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.tree.ChildRoleBase; import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; -public class ParameterElement extends CompositeElement{ +public class ParameterElement extends CompositeElement { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.java.ParameterElement"); - public ParameterElement() { - super(JavaElementType.PARAMETER); - } - - protected ParameterElement(IElementType type) { + public ParameterElement(@NotNull IElementType type) { super(type); } @Override public int getTextOffset() { - return findChildByRole(ChildRole.NAME).getStartOffset(); + ASTNode node = findChildByType(JavaParameterElementType.ID_TYPES); + return node != null ? node.getStartOffset() : getStartOffset(); } @Override - public ASTNode findChildByRole(int role){ + public ASTNode findChildByRole(int role) { LOG.assertTrue(ChildRole.isUnique(role)); - switch(role){ - default: - return null; - - case ChildRole.MODIFIER_LIST: - return findChildByType(JavaElementType.MODIFIER_LIST); - - case ChildRole.NAME: - return findChildByType(JavaTokenType.IDENTIFIER); - - case ChildRole.TYPE: - return findChildByType(JavaElementType.TYPE); + if (role == ChildRole.MODIFIER_LIST) { + return findChildByType(JavaElementType.MODIFIER_LIST); + } + else if (role == ChildRole.NAME) { + return findChildByType(JavaTokenType.IDENTIFIER); + } + else if (role == ChildRole.TYPE) { + return findChildByType(JavaElementType.TYPE); + } + else { + return null; } } @Override public int getChildRole(ASTNode child) { LOG.assertTrue(child.getTreeParent() == this); + IElementType i = child.getElementType(); if (i == JavaElementType.MODIFIER_LIST) { return ChildRole.MODIFIER_LIST; @@ -77,4 +76,3 @@ public class ParameterElement extends CompositeElement{ } } } - diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java index a42c0bc4328f..4002b1646ac8 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LightTreeUtil.java @@ -42,6 +42,17 @@ public class LightTreeUtil { return null; } + @Nullable + public static LighterASTNode firstChildOfType(@NotNull LighterAST tree, @NotNull LighterASTNode node, @NotNull TokenSet types) { + List children = tree.getChildren(node); + for (int i = 0, size = children.size(); i < size; ++i) { + LighterASTNode child = children.get(i); + if (types.contains(child.getTokenType())) return child; + } + + return null; + } + @NotNull public static LighterASTNode requiredChildOfType(@NotNull LighterAST tree, @NotNull LighterASTNode node, @NotNull IElementType type) { LighterASTNode child = firstChildOfType(tree, node, type); @@ -49,6 +60,13 @@ public class LightTreeUtil { return child; } + @NotNull + public static LighterASTNode requiredChildOfType(@NotNull LighterAST tree, @NotNull LighterASTNode node, @NotNull TokenSet types) { + LighterASTNode child = firstChildOfType(tree, node, types); + assert child != null : "Required child " + types + " not found in " + node.getTokenType() + ": " + tree.getChildren(node); + return child; + } + @NotNull public static List getChildrenOfType(@NotNull LighterAST tree, @NotNull LighterASTNode node, @NotNull IElementType type) { List result = null;