mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-57347 (type parameters in new expression)
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -115,7 +115,7 @@ public class FileParser {
|
||||
}
|
||||
}
|
||||
|
||||
final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, false, false, false);
|
||||
final PsiBuilder.Marker ref = ReferenceParser.parseJavaCodeReference(builder, true, false, false, false, false);
|
||||
if (ref == null) {
|
||||
statement.rollbackTo();
|
||||
return null;
|
||||
|
||||
@@ -1,346 +1,349 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.lang.java.parser;
|
||||
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.lang.PsiBuilderUtil.expect;
|
||||
import static com.intellij.lang.PsiBuilderUtil.nextTokenType;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.*;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.emptyElement;
|
||||
|
||||
|
||||
public class ReferenceParser {
|
||||
public static final int EAT_LAST_DOT = 0x01;
|
||||
public static final int ELLIPSIS = 0x02;
|
||||
public static final int WILDCARD = 0x04;
|
||||
public static final int DIAMONDS = 0x08;
|
||||
|
||||
public static class TypeInfo {
|
||||
public boolean isPrimitive = false;
|
||||
public boolean isParameterized = false;
|
||||
public boolean isArray = false;
|
||||
public boolean isVarArg = false;
|
||||
public boolean hasErrors = false;
|
||||
public PsiBuilder.Marker marker = null;
|
||||
}
|
||||
|
||||
private static final TokenSet WILDCARD_KEYWORD_SET = TokenSet.create(JavaTokenType.EXTENDS_KEYWORD, JavaTokenType.SUPER_KEYWORD);
|
||||
|
||||
private ReferenceParser() { }
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseType(final PsiBuilder builder, final int flags) {
|
||||
final TypeInfo typeInfo = parseTypeInfo(builder, flags);
|
||||
return typeInfo != null ? typeInfo.marker : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TypeInfo parseTypeInfo(final PsiBuilder builder, final int flags) {
|
||||
return parseTypeInfo(builder, isSet(flags, EAT_LAST_DOT), isSet(flags, WILDCARD), isSet(flags, DIAMONDS), isSet(flags, ELLIPSIS));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static TypeInfo parseTypeInfo(final PsiBuilder builder,
|
||||
final boolean eatLastDot, final boolean wildcard, final boolean diamonds, final boolean ellipsis) {
|
||||
if (builder.getTokenType() == null) return null;
|
||||
|
||||
final TypeInfo typeInfo = new TypeInfo();
|
||||
|
||||
final boolean annotationsSupported = areTypeAnnotationsSupported(builder);
|
||||
PsiBuilder.Marker type = builder.mark();
|
||||
if (annotationsSupported) {
|
||||
DeclarationParser.parseAnnotations(builder);
|
||||
}
|
||||
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (expect(builder, ElementType.PRIMITIVE_TYPE_BIT_SET)) {
|
||||
typeInfo.isPrimitive = true;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.IDENTIFIER) {
|
||||
parseJavaCodeReference(builder, eatLastDot, true, annotationsSupported, false, false, diamonds, typeInfo);
|
||||
}
|
||||
else if (wildcard && tokenType == JavaTokenType.QUEST) {
|
||||
type.drop();
|
||||
typeInfo.marker = parseWildcardType(builder);
|
||||
return typeInfo.marker != null ? typeInfo : null;
|
||||
}
|
||||
else if (diamonds && tokenType == JavaTokenType.GT) {
|
||||
emptyElement(builder, JavaElementType.DIAMOND_TYPE);
|
||||
type.done(JavaElementType.TYPE);
|
||||
typeInfo.marker = type;
|
||||
return typeInfo;
|
||||
}
|
||||
else {
|
||||
type.drop();
|
||||
return null;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
type.done(JavaElementType.TYPE);
|
||||
if (annotationsSupported) {
|
||||
DeclarationParser.parseAnnotations(builder);
|
||||
}
|
||||
|
||||
final PsiBuilder.Marker bracket = builder.mark();
|
||||
if (!expect(builder, JavaTokenType.LBRACKET)) {
|
||||
bracket.drop();
|
||||
break;
|
||||
}
|
||||
if (!expect(builder, JavaTokenType.RBRACKET)) {
|
||||
bracket.rollbackTo();
|
||||
break;
|
||||
}
|
||||
bracket.drop();
|
||||
typeInfo.isArray = true;
|
||||
|
||||
type = type.precede();
|
||||
}
|
||||
|
||||
if (ellipsis && builder.getTokenType() == JavaTokenType.ELLIPSIS) {
|
||||
type = type.precede();
|
||||
builder.advanceLexer();
|
||||
type.done(JavaElementType.TYPE);
|
||||
typeInfo.isVarArg = true;
|
||||
}
|
||||
|
||||
typeInfo.marker = type;
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
private static boolean isSet(final int mask, final int flag) {
|
||||
return (mask & flag) != 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiBuilder.Marker parseWildcardType(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker type = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
if (expect(builder, WILDCARD_KEYWORD_SET)) {
|
||||
if (parseTypeInfo(builder, EAT_LAST_DOT) == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.type"));
|
||||
}
|
||||
}
|
||||
|
||||
type.done(JavaElementType.TYPE);
|
||||
return type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot,
|
||||
final boolean parameterList, final boolean annotations, final boolean diamonds) {
|
||||
return parseJavaCodeReference(builder, eatLastDot, parameterList, annotations, false, false, diamonds, new TypeInfo());
|
||||
}
|
||||
|
||||
public static boolean parseImportCodeReference(final PsiBuilder builder, final boolean isStatic) {
|
||||
final TypeInfo typeInfo = new TypeInfo();
|
||||
parseJavaCodeReference(builder, true, false, false, true, isStatic, false, typeInfo);
|
||||
return !typeInfo.hasErrors;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot,
|
||||
final boolean parameterList, final boolean annotations,
|
||||
final boolean isImport, final boolean isStaticImport,
|
||||
final boolean diamonds, final TypeInfo typeInfo) {
|
||||
PsiBuilder.Marker refElement = builder.mark();
|
||||
|
||||
if (annotations) {
|
||||
DeclarationParser.parseAnnotations(builder);
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
refElement.rollbackTo();
|
||||
if (isImport) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
typeInfo.hasErrors = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parameterList) {
|
||||
typeInfo.isParameterized = parseReferenceParameterList(builder, true, diamonds);
|
||||
}
|
||||
else {
|
||||
if (!isStaticImport || builder.getTokenType() == JavaTokenType.DOT) {
|
||||
emptyElement(builder, JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasIdentifier;
|
||||
while (builder.getTokenType() == JavaTokenType.DOT) {
|
||||
refElement.done(JavaElementType.JAVA_CODE_REFERENCE);
|
||||
|
||||
final PsiBuilder.Marker dotPos = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
if (expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
hasIdentifier = true;
|
||||
}
|
||||
else if (isImport && expect(builder, JavaTokenType.ASTERISK)) {
|
||||
dotPos.drop();
|
||||
return refElement;
|
||||
}
|
||||
else {
|
||||
if (!eatLastDot) {
|
||||
dotPos.rollbackTo();
|
||||
return refElement;
|
||||
}
|
||||
hasIdentifier = false;
|
||||
}
|
||||
dotPos.drop();
|
||||
|
||||
final PsiBuilder.Marker prevElement = refElement;
|
||||
refElement = refElement.precede();
|
||||
|
||||
if (!hasIdentifier) {
|
||||
typeInfo.hasErrors = true;
|
||||
if (isImport) {
|
||||
error(builder, JavaErrorMessages.message("import.statement.identifier.or.asterisk.expected."));
|
||||
refElement.drop();
|
||||
return prevElement;
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
emptyElement(builder, JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (parameterList) {
|
||||
typeInfo.isParameterized = parseReferenceParameterList(builder, true, diamonds);
|
||||
}
|
||||
else if (!isStaticImport || builder.getTokenType() == JavaTokenType.DOT) {
|
||||
emptyElement(builder, JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
}
|
||||
}
|
||||
|
||||
refElement.done(isStaticImport ? JavaElementType.IMPORT_STATIC_REFERENCE : JavaElementType.JAVA_CODE_REFERENCE);
|
||||
return refElement;
|
||||
}
|
||||
|
||||
public static boolean parseReferenceParameterList(final PsiBuilder builder, final boolean wildcard, final boolean diamonds) {
|
||||
final PsiBuilder.Marker list = builder.mark();
|
||||
if (!expect(builder, JavaTokenType.LT)) {
|
||||
list.done(JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isOk = true;
|
||||
while (true) {
|
||||
if (parseTypeInfo(builder, true, wildcard, diamonds, false) == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
|
||||
if (expect(builder, JavaTokenType.GT)) {
|
||||
break;
|
||||
}
|
||||
else if (!expectOrError(builder, JavaTokenType.COMMA, JavaErrorMessages.message("expected.gt.or.comma"))) {
|
||||
isOk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list.done(JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
return isOk;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiBuilder.Marker parseTypeParameters(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker list = builder.mark();
|
||||
if (!expect(builder, JavaTokenType.LT)) {
|
||||
list.done(JavaElementType.TYPE_PARAMETER_LIST);
|
||||
return list;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
final PsiBuilder.Marker param = parseTypeParameter(builder);
|
||||
if (param == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.type.parameter"));
|
||||
}
|
||||
if (!expect(builder, JavaTokenType.COMMA)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.GT)) {
|
||||
// hack for completion
|
||||
if (builder.getTokenType() == JavaTokenType.IDENTIFIER) {
|
||||
if (nextTokenType(builder) == JavaTokenType.GT) {
|
||||
final PsiBuilder.Marker errorElement = builder.mark();
|
||||
builder.advanceLexer();
|
||||
errorElement.error(JavaErrorMessages.message("unexpected.identifier"));
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.gt"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.gt"));
|
||||
}
|
||||
}
|
||||
|
||||
list.done(JavaElementType.TYPE_PARAMETER_LIST);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiBuilder.Marker parseTypeParameter(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker param = builder.mark();
|
||||
|
||||
DeclarationParser.parseAnnotations(builder);
|
||||
if (!expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
param.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
|
||||
parseReferenceList(builder, JavaTokenType.EXTENDS_KEYWORD, JavaElementType.EXTENDS_BOUND_LIST, JavaTokenType.AND);
|
||||
|
||||
param.done(JavaElementType.TYPE_PARAMETER);
|
||||
return param;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiBuilder.Marker parseReferenceList(final PsiBuilder builder, final IElementType start,
|
||||
final IElementType type, final IElementType delimiter) {
|
||||
final PsiBuilder.Marker element = builder.mark();
|
||||
|
||||
if (expect(builder, start)) {
|
||||
while (true) {
|
||||
final PsiBuilder.Marker classReference = parseJavaCodeReference(builder, true, true, true, false);
|
||||
if (classReference == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
if (!expect(builder, delimiter)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
element.done(type);
|
||||
return element;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2000-2010 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.lang.java.parser;
|
||||
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
import com.intellij.psi.impl.source.tree.JavaElementType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static com.intellij.lang.PsiBuilderUtil.expect;
|
||||
import static com.intellij.lang.PsiBuilderUtil.nextTokenType;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.*;
|
||||
import static com.intellij.lang.java.parser.JavaParserUtil.emptyElement;
|
||||
|
||||
|
||||
public class ReferenceParser {
|
||||
public static final int EAT_LAST_DOT = 0x01;
|
||||
public static final int ELLIPSIS = 0x02;
|
||||
public static final int WILDCARD = 0x04;
|
||||
public static final int DIAMONDS = 0x08;
|
||||
|
||||
public static class TypeInfo {
|
||||
public boolean isPrimitive = false;
|
||||
public boolean isParameterized = false;
|
||||
public boolean isArray = false;
|
||||
public boolean isVarArg = false;
|
||||
public boolean hasErrors = false;
|
||||
public PsiBuilder.Marker marker = null;
|
||||
}
|
||||
|
||||
private static final TokenSet WILDCARD_KEYWORD_SET = TokenSet.create(JavaTokenType.EXTENDS_KEYWORD, JavaTokenType.SUPER_KEYWORD);
|
||||
|
||||
private ReferenceParser() { }
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseType(final PsiBuilder builder, final int flags) {
|
||||
final TypeInfo typeInfo = parseTypeInfo(builder, flags);
|
||||
return typeInfo != null ? typeInfo.marker : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TypeInfo parseTypeInfo(final PsiBuilder builder, final int flags) {
|
||||
return parseTypeInfo(builder, isSet(flags, EAT_LAST_DOT), isSet(flags, WILDCARD), isSet(flags, DIAMONDS), isSet(flags, ELLIPSIS));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static TypeInfo parseTypeInfo(final PsiBuilder builder,
|
||||
final boolean eatLastDot, final boolean wildcard, final boolean diamonds, final boolean ellipsis) {
|
||||
if (builder.getTokenType() == null) return null;
|
||||
|
||||
final TypeInfo typeInfo = new TypeInfo();
|
||||
|
||||
final boolean annotationsSupported = areTypeAnnotationsSupported(builder);
|
||||
PsiBuilder.Marker type = builder.mark();
|
||||
if (annotationsSupported) {
|
||||
DeclarationParser.parseAnnotations(builder);
|
||||
}
|
||||
|
||||
final IElementType tokenType = builder.getTokenType();
|
||||
if (expect(builder, ElementType.PRIMITIVE_TYPE_BIT_SET)) {
|
||||
typeInfo.isPrimitive = true;
|
||||
}
|
||||
else if (tokenType == JavaTokenType.IDENTIFIER) {
|
||||
parseJavaCodeReference(builder, eatLastDot, true, annotationsSupported, false, false, false, diamonds, typeInfo);
|
||||
}
|
||||
else if (wildcard && tokenType == JavaTokenType.QUEST) {
|
||||
type.drop();
|
||||
typeInfo.marker = parseWildcardType(builder);
|
||||
return typeInfo.marker != null ? typeInfo : null;
|
||||
}
|
||||
else if (diamonds && tokenType == JavaTokenType.GT) {
|
||||
emptyElement(builder, JavaElementType.DIAMOND_TYPE);
|
||||
type.done(JavaElementType.TYPE);
|
||||
typeInfo.marker = type;
|
||||
return typeInfo;
|
||||
}
|
||||
else {
|
||||
type.drop();
|
||||
return null;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
type.done(JavaElementType.TYPE);
|
||||
if (annotationsSupported) {
|
||||
DeclarationParser.parseAnnotations(builder);
|
||||
}
|
||||
|
||||
final PsiBuilder.Marker bracket = builder.mark();
|
||||
if (!expect(builder, JavaTokenType.LBRACKET)) {
|
||||
bracket.drop();
|
||||
break;
|
||||
}
|
||||
if (!expect(builder, JavaTokenType.RBRACKET)) {
|
||||
bracket.rollbackTo();
|
||||
break;
|
||||
}
|
||||
bracket.drop();
|
||||
typeInfo.isArray = true;
|
||||
|
||||
type = type.precede();
|
||||
}
|
||||
|
||||
if (ellipsis && builder.getTokenType() == JavaTokenType.ELLIPSIS) {
|
||||
type = type.precede();
|
||||
builder.advanceLexer();
|
||||
type.done(JavaElementType.TYPE);
|
||||
typeInfo.isVarArg = true;
|
||||
}
|
||||
|
||||
typeInfo.marker = type;
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
private static boolean isSet(final int mask, final int flag) {
|
||||
return (mask & flag) != 0;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiBuilder.Marker parseWildcardType(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker type = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
if (expect(builder, WILDCARD_KEYWORD_SET)) {
|
||||
if (parseTypeInfo(builder, EAT_LAST_DOT) == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.type"));
|
||||
}
|
||||
}
|
||||
|
||||
type.done(JavaElementType.TYPE);
|
||||
return type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot, final boolean parameterList,
|
||||
final boolean annotations, final boolean isNew, final boolean diamonds) {
|
||||
return parseJavaCodeReference(builder, eatLastDot, parameterList, annotations, false, false, isNew, diamonds, new TypeInfo());
|
||||
}
|
||||
|
||||
public static boolean parseImportCodeReference(final PsiBuilder builder, final boolean isStatic) {
|
||||
final TypeInfo typeInfo = new TypeInfo();
|
||||
parseJavaCodeReference(builder, true, false, false, true, isStatic, false, false, typeInfo);
|
||||
return !typeInfo.hasErrors;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiBuilder.Marker parseJavaCodeReference(final PsiBuilder builder, final boolean eatLastDot, final boolean parameterList,
|
||||
final boolean annotations, final boolean isImport, final boolean isStaticImport,
|
||||
final boolean isNew, final boolean diamonds, final TypeInfo typeInfo) {
|
||||
PsiBuilder.Marker refElement = builder.mark();
|
||||
|
||||
if (annotations) {
|
||||
DeclarationParser.parseAnnotations(builder);
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
refElement.rollbackTo();
|
||||
if (isImport) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
typeInfo.hasErrors = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (parameterList) {
|
||||
typeInfo.isParameterized = parseReferenceParameterList(builder, true, diamonds);
|
||||
}
|
||||
else {
|
||||
if (!isStaticImport || builder.getTokenType() == JavaTokenType.DOT) {
|
||||
emptyElement(builder, JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasIdentifier;
|
||||
while (builder.getTokenType() == JavaTokenType.DOT) {
|
||||
refElement.done(JavaElementType.JAVA_CODE_REFERENCE);
|
||||
|
||||
if (isNew && typeInfo.isParameterized) {
|
||||
return refElement;
|
||||
}
|
||||
|
||||
final PsiBuilder.Marker dotPos = builder.mark();
|
||||
builder.advanceLexer();
|
||||
|
||||
if (expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
hasIdentifier = true;
|
||||
}
|
||||
else if (isImport && expect(builder, JavaTokenType.ASTERISK)) {
|
||||
dotPos.drop();
|
||||
return refElement;
|
||||
}
|
||||
else {
|
||||
if (!eatLastDot) {
|
||||
dotPos.rollbackTo();
|
||||
return refElement;
|
||||
}
|
||||
hasIdentifier = false;
|
||||
}
|
||||
dotPos.drop();
|
||||
|
||||
final PsiBuilder.Marker prevElement = refElement;
|
||||
refElement = refElement.precede();
|
||||
|
||||
if (!hasIdentifier) {
|
||||
typeInfo.hasErrors = true;
|
||||
if (isImport) {
|
||||
error(builder, JavaErrorMessages.message("import.statement.identifier.or.asterisk.expected."));
|
||||
refElement.drop();
|
||||
return prevElement;
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
emptyElement(builder, JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (parameterList) {
|
||||
typeInfo.isParameterized = parseReferenceParameterList(builder, true, diamonds);
|
||||
}
|
||||
else if (!isStaticImport || builder.getTokenType() == JavaTokenType.DOT) {
|
||||
emptyElement(builder, JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
}
|
||||
}
|
||||
|
||||
refElement.done(isStaticImport ? JavaElementType.IMPORT_STATIC_REFERENCE : JavaElementType.JAVA_CODE_REFERENCE);
|
||||
return refElement;
|
||||
}
|
||||
|
||||
public static boolean parseReferenceParameterList(final PsiBuilder builder, final boolean wildcard, final boolean diamonds) {
|
||||
final PsiBuilder.Marker list = builder.mark();
|
||||
if (!expect(builder, JavaTokenType.LT)) {
|
||||
list.done(JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isOk = true;
|
||||
while (true) {
|
||||
if (parseTypeInfo(builder, true, wildcard, diamonds, false) == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
|
||||
if (expect(builder, JavaTokenType.GT)) {
|
||||
break;
|
||||
}
|
||||
else if (!expectOrError(builder, JavaTokenType.COMMA, JavaErrorMessages.message("expected.gt.or.comma"))) {
|
||||
isOk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list.done(JavaElementType.REFERENCE_PARAMETER_LIST);
|
||||
return isOk;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiBuilder.Marker parseTypeParameters(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker list = builder.mark();
|
||||
if (!expect(builder, JavaTokenType.LT)) {
|
||||
list.done(JavaElementType.TYPE_PARAMETER_LIST);
|
||||
return list;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
final PsiBuilder.Marker param = parseTypeParameter(builder);
|
||||
if (param == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.type.parameter"));
|
||||
}
|
||||
if (!expect(builder, JavaTokenType.COMMA)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!expect(builder, JavaTokenType.GT)) {
|
||||
// hack for completion
|
||||
if (builder.getTokenType() == JavaTokenType.IDENTIFIER) {
|
||||
if (nextTokenType(builder) == JavaTokenType.GT) {
|
||||
final PsiBuilder.Marker errorElement = builder.mark();
|
||||
builder.advanceLexer();
|
||||
errorElement.error(JavaErrorMessages.message("unexpected.identifier"));
|
||||
builder.advanceLexer();
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.gt"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(builder, JavaErrorMessages.message("expected.gt"));
|
||||
}
|
||||
}
|
||||
|
||||
list.done(JavaElementType.TYPE_PARAMETER_LIST);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiBuilder.Marker parseTypeParameter(final PsiBuilder builder) {
|
||||
final PsiBuilder.Marker param = builder.mark();
|
||||
|
||||
DeclarationParser.parseAnnotations(builder);
|
||||
if (!expect(builder, JavaTokenType.IDENTIFIER)) {
|
||||
param.rollbackTo();
|
||||
return null;
|
||||
}
|
||||
|
||||
parseReferenceList(builder, JavaTokenType.EXTENDS_KEYWORD, JavaElementType.EXTENDS_BOUND_LIST, JavaTokenType.AND);
|
||||
|
||||
param.done(JavaElementType.TYPE_PARAMETER);
|
||||
return param;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiBuilder.Marker parseReferenceList(final PsiBuilder builder, final IElementType start,
|
||||
final IElementType type, final IElementType delimiter) {
|
||||
final PsiBuilder.Marker element = builder.mark();
|
||||
|
||||
if (expect(builder, start)) {
|
||||
while (true) {
|
||||
final PsiBuilder.Marker classReference = parseJavaCodeReference(builder, true, true, true, false, false);
|
||||
if (classReference == null) {
|
||||
error(builder, JavaErrorMessages.message("expected.identifier"));
|
||||
}
|
||||
if (!expect(builder, delimiter)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
element.done(type);
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,267 +1,267 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.tree;
|
||||
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.lang.java.parser.ExpressionParser;
|
||||
import com.intellij.lang.java.parser.JavaParserUtil;
|
||||
import com.intellij.lang.java.parser.ReferenceParser;
|
||||
import com.intellij.lang.java.parser.StatementParser;
|
||||
import com.intellij.lexer.JavaLexer;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.source.parsing.JavaParsingContext;
|
||||
import com.intellij.psi.impl.source.parsing.Parsing;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiCodeBlockImpl;
|
||||
import com.intellij.psi.text.BlockSupport;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IErrorCounterReparseableElementType;
|
||||
import com.intellij.psi.tree.ILazyParseableElementType;
|
||||
import com.intellij.psi.tree.ILightLazyParseableElementType;
|
||||
import com.intellij.psi.tree.java.IJavaElementType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.CharTable;
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure;
|
||||
|
||||
import static com.intellij.lang.PsiBuilderUtil.expect;
|
||||
|
||||
public interface JavaElementType {
|
||||
IElementType CLASS = JavaStubElementTypes.CLASS;
|
||||
IElementType ANONYMOUS_CLASS = JavaStubElementTypes.ANONYMOUS_CLASS;
|
||||
IElementType ENUM_CONSTANT_INITIALIZER = JavaStubElementTypes.ENUM_CONSTANT_INITIALIZER;
|
||||
|
||||
IElementType TYPE_PARAMETER_LIST = JavaStubElementTypes.TYPE_PARAMETER_LIST;
|
||||
IElementType TYPE_PARAMETER = JavaStubElementTypes.TYPE_PARAMETER;
|
||||
|
||||
IElementType IMPORT_LIST = JavaStubElementTypes.IMPORT_LIST;
|
||||
IElementType IMPORT_STATEMENT = JavaStubElementTypes.IMPORT_STATEMENT;
|
||||
IElementType IMPORT_STATIC_STATEMENT = JavaStubElementTypes.IMPORT_STATIC_STATEMENT;
|
||||
|
||||
IElementType MODIFIER_LIST = JavaStubElementTypes.MODIFIER_LIST;
|
||||
IElementType ANNOTATION = JavaStubElementTypes.ANNOTATION;
|
||||
IElementType EXTENDS_LIST = JavaStubElementTypes.EXTENDS_LIST;
|
||||
IElementType IMPLEMENTS_LIST = JavaStubElementTypes.IMPLEMENTS_LIST;
|
||||
IElementType FIELD = JavaStubElementTypes.FIELD;
|
||||
IElementType ENUM_CONSTANT = JavaStubElementTypes.ENUM_CONSTANT;
|
||||
IElementType METHOD = JavaStubElementTypes.METHOD;
|
||||
IElementType ANNOTATION_METHOD = JavaStubElementTypes.ANNOTATION_METHOD;
|
||||
|
||||
IElementType CLASS_INITIALIZER = JavaStubElementTypes.CLASS_INITIALIZER;
|
||||
IElementType PARAMETER = JavaStubElementTypes.PARAMETER;
|
||||
IElementType PARAMETER_LIST = JavaStubElementTypes.PARAMETER_LIST;
|
||||
IElementType EXTENDS_BOUND_LIST = JavaStubElementTypes.EXTENDS_BOUND_LIST;
|
||||
IElementType THROWS_LIST = JavaStubElementTypes.THROWS_LIST;
|
||||
|
||||
IElementType IMPORT_STATIC_REFERENCE = new IJavaElementType("IMPORT_STATIC_REFERENCE");
|
||||
IElementType TYPE = new IJavaElementType("TYPE");
|
||||
IElementType DIAMOND_TYPE = new IJavaElementType("DIAMOND_TYPE");
|
||||
IElementType REFERENCE_PARAMETER_LIST = new IJavaElementType("REFERENCE_PARAMETER_LIST", true);
|
||||
IElementType JAVA_CODE_REFERENCE = new IJavaElementType("JAVA_CODE_REFERENCE");
|
||||
IElementType PACKAGE_STATEMENT = new IJavaElementType("PACKAGE_STATEMENT");
|
||||
|
||||
IElementType LOCAL_VARIABLE = new IJavaElementType("LOCAL_VARIABLE");
|
||||
IElementType REFERENCE_EXPRESSION = new IJavaElementType("REFERENCE_EXPRESSION");
|
||||
IElementType LITERAL_EXPRESSION = new IJavaElementType("LITERAL_EXPRESSION");
|
||||
IElementType THIS_EXPRESSION = new IJavaElementType("THIS_EXPRESSION");
|
||||
IElementType SUPER_EXPRESSION = new IJavaElementType("SUPER_EXPRESSION");
|
||||
IElementType PARENTH_EXPRESSION = new IJavaElementType("PARENTH_EXPRESSION");
|
||||
IElementType METHOD_CALL_EXPRESSION = new IJavaElementType("METHOD_CALL_EXPRESSION");
|
||||
IElementType TYPE_CAST_EXPRESSION = new IJavaElementType("TYPE_CAST_EXPRESSION");
|
||||
IElementType PREFIX_EXPRESSION = new IJavaElementType("PREFIX_EXPRESSION");
|
||||
IElementType POSTFIX_EXPRESSION = new IJavaElementType("POSTFIX_EXPRESSION");
|
||||
IElementType BINARY_EXPRESSION = new IJavaElementType("BINARY_EXPRESSION");
|
||||
IElementType CONDITIONAL_EXPRESSION = new IJavaElementType("CONDITIONAL_EXPRESSION");
|
||||
IElementType ASSIGNMENT_EXPRESSION = new IJavaElementType("ASSIGNMENT_EXPRESSION");
|
||||
IElementType NEW_EXPRESSION = new IJavaElementType("NEW_EXPRESSION");
|
||||
IElementType ARRAY_ACCESS_EXPRESSION = new IJavaElementType("ARRAY_ACCESS_EXPRESSION");
|
||||
IElementType ARRAY_INITIALIZER_EXPRESSION = new IJavaElementType("ARRAY_INITIALIZER_EXPRESSION");
|
||||
IElementType INSTANCE_OF_EXPRESSION = new IJavaElementType("INSTANCE_OF_EXPRESSION");
|
||||
IElementType CLASS_OBJECT_ACCESS_EXPRESSION = new IJavaElementType("CLASS_OBJECT_ACCESS_EXPRESSION");
|
||||
IElementType EMPTY_EXPRESSION = new IJavaElementType("EMPTY_EXPRESSION", true);
|
||||
|
||||
IElementType EXPRESSION_LIST = new IJavaElementType("EXPRESSION_LIST", true);
|
||||
|
||||
IElementType EMPTY_STATEMENT = new IJavaElementType("EMPTY_STATEMENT");
|
||||
IElementType BLOCK_STATEMENT = new IJavaElementType("BLOCK_STATEMENT");
|
||||
IElementType EXPRESSION_STATEMENT = new IJavaElementType("EXPRESSION_STATEMENT");
|
||||
IElementType EXPRESSION_LIST_STATEMENT = new IJavaElementType("EXPRESSION_LIST_STATEMENT");
|
||||
IElementType DECLARATION_STATEMENT = new IJavaElementType("DECLARATION_STATEMENT");
|
||||
IElementType IF_STATEMENT = new IJavaElementType("IF_STATEMENT");
|
||||
IElementType WHILE_STATEMENT = new IJavaElementType("WHILE_STATEMENT");
|
||||
IElementType FOR_STATEMENT = new IJavaElementType("FOR_STATEMENT");
|
||||
IElementType FOREACH_STATEMENT = new IJavaElementType("FOREACH_STATEMENT");
|
||||
IElementType DO_WHILE_STATEMENT = new IJavaElementType("DO_WHILE_STATEMENT");
|
||||
IElementType SWITCH_STATEMENT = new IJavaElementType("SWITCH_STATEMENT");
|
||||
IElementType SWITCH_LABEL_STATEMENT = new IJavaElementType("SWITCH_LABEL_STATEMENT");
|
||||
IElementType BREAK_STATEMENT = new IJavaElementType("BREAK_STATEMENT");
|
||||
IElementType CONTINUE_STATEMENT = new IJavaElementType("CONTINUE_STATEMENT");
|
||||
IElementType RETURN_STATEMENT = new IJavaElementType("RETURN_STATEMENT");
|
||||
IElementType THROW_STATEMENT = new IJavaElementType("THROW_STATEMENT");
|
||||
IElementType SYNCHRONIZED_STATEMENT = new IJavaElementType("SYNCHRONIZED_STATEMENT");
|
||||
IElementType TRY_STATEMENT = new IJavaElementType("TRY_STATEMENT");
|
||||
IElementType LABELED_STATEMENT = new IJavaElementType("LABELED_STATEMENT");
|
||||
IElementType ASSERT_STATEMENT = new IJavaElementType("ASSERT_STATEMENT");
|
||||
|
||||
IElementType CATCH_SECTION = new IJavaElementType("CATCH_SECTION");
|
||||
|
||||
IElementType ANNOTATION_ARRAY_INITIALIZER = new IJavaElementType("ANNOTATION_ARRAY_INITIALIZER");
|
||||
IElementType NAME_VALUE_PAIR = new IJavaElementType("NAME_VALUE_PAIR", true);
|
||||
IElementType ANNOTATION_PARAMETER_LIST = new IJavaElementType("ANNOTATION_PARAMETER_LIST", true);
|
||||
IElementType METHOD_RECEIVER = new IJavaElementType("METHOD_RECEIVER");
|
||||
|
||||
class ICodeBlockElementType extends IErrorCounterReparseableElementType {
|
||||
private ICodeBlockElementType() {
|
||||
super("CODE_BLOCK", StdLanguages.JAVA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode createNode(final CharSequence text) {
|
||||
return new PsiCodeBlockImpl(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
final PsiBuilder builder = JavaParserUtil.createBuilder(chameleon);
|
||||
StatementParser.parseCodeBlockDeep(builder, true);
|
||||
return builder.getTreeBuilt().getFirstChildNode();
|
||||
}
|
||||
|
||||
final CharSequence seq = chameleon.getChars();
|
||||
|
||||
ASTNode original = chameleon.getUserData(BlockSupport.TREE_TO_BE_REPARSED);
|
||||
ASTNode context = original != null ? original : chameleon.getTreeParent();
|
||||
|
||||
final PsiManager manager = context.getPsi().getManager();
|
||||
final CharTable table = SharedImplUtil.findCharTableByTree(context);
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(TreeUtil.getFileElement((TreeElement)context).getPsi());
|
||||
JavaParsingContext parsingContext = new JavaParsingContext(table, languageLevel);
|
||||
return parsingContext.getStatementParsing().parseCodeBlockText(manager, new JavaLexer(languageLevel),
|
||||
seq, 0, seq.length(), 0).getFirstChildNode();
|
||||
}
|
||||
|
||||
public int getErrorsCount(final CharSequence seq, final Project project) {
|
||||
final Lexer lexer = new JavaLexer(LanguageLevel.HIGHEST);
|
||||
|
||||
lexer.start(seq);
|
||||
if (lexer.getTokenType() != JavaTokenType.LBRACE) return FATAL_ERROR;
|
||||
lexer.advance();
|
||||
int balance = 1;
|
||||
while (true) {
|
||||
IElementType type = lexer.getTokenType();
|
||||
if (type == null) break;
|
||||
if (balance == 0) return FATAL_ERROR;
|
||||
if (type == JavaTokenType.LBRACE) {
|
||||
balance++;
|
||||
}
|
||||
else if (type == JavaTokenType.RBRACE) {
|
||||
balance--;
|
||||
}
|
||||
lexer.advance();
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
}
|
||||
|
||||
class ICodeBlockNewElementType extends ICodeBlockElementType implements ILightLazyParseableElementType {
|
||||
private ICodeBlockNewElementType() { }
|
||||
|
||||
public FlyweightCapableTreeStructure<LighterASTNode> parseContents(final LighterLazyParseableNode chameleon) {
|
||||
final PsiBuilder builder = JavaParserUtil.createBuilder(chameleon);
|
||||
StatementParser.parseCodeBlockDeep(builder, true);
|
||||
return builder.getLightTree();
|
||||
}
|
||||
}
|
||||
|
||||
ILazyParseableElementType CODE_BLOCK = JavaParserDefinition.USE_NEW_PARSER ? new ICodeBlockNewElementType() : new ICodeBlockElementType();
|
||||
|
||||
IElementType STATEMENTS = new ICodeFragmentElementType("STATEMENTS", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
StatementParser.parseStatements(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
final PsiManager manager = ((FileElement)chameleon).getManager();
|
||||
final CharTable table = SharedImplUtil.findCharTableByTree(chameleon);
|
||||
JavaParsingContext context = new JavaParsingContext(table, LanguageLevel.HIGHEST);
|
||||
return context.getStatementParsing().parseStatements(manager, null, chars, 0, chars.length(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
IElementType EXPRESSION_TEXT = new ICodeFragmentElementType("EXPRESSION_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ExpressionParser.parse(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
final PsiManager manager = ((FileElement)chameleon).getManager();
|
||||
final JavaParsingContext context = new JavaParsingContext(SharedImplUtil.findCharTableByTree(chameleon), LanguageLevel.HIGHEST);
|
||||
return context.getExpressionParsing().parseExpressionTextFragment(manager, chars, 0, chars.length(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
IElementType REFERENCE_TEXT = new ICodeFragmentElementType("REFERENCE_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseJavaCodeReference(builder, false, true, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
return Parsing.parseJavaCodeReferenceText(((FileElement)chameleon).getManager(), chars, 0, chars.length(),
|
||||
SharedImplUtil.findCharTableByTree(chameleon), true);
|
||||
}
|
||||
};
|
||||
|
||||
IElementType TYPE_TEXT = new ICodeFragmentElementType("TYPE_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD);
|
||||
expect(builder, JavaTokenType.ELLIPSIS); // todo[r.sh] parse ellipsis and fix PsiTypeCodeFragmentImpl.getType()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
return Parsing.parseTypeText(((FileElement)chameleon).getManager(), null, chars, 0, chars.length(), 0,
|
||||
SharedImplUtil.findCharTableByTree(chameleon));
|
||||
}
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.psi.impl.source.tree;
|
||||
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lang.java.JavaParserDefinition;
|
||||
import com.intellij.lang.java.parser.ExpressionParser;
|
||||
import com.intellij.lang.java.parser.JavaParserUtil;
|
||||
import com.intellij.lang.java.parser.ReferenceParser;
|
||||
import com.intellij.lang.java.parser.StatementParser;
|
||||
import com.intellij.lexer.JavaLexer;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
|
||||
import com.intellij.psi.impl.source.parsing.JavaParsingContext;
|
||||
import com.intellij.psi.impl.source.parsing.Parsing;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiCodeBlockImpl;
|
||||
import com.intellij.psi.text.BlockSupport;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IErrorCounterReparseableElementType;
|
||||
import com.intellij.psi.tree.ILazyParseableElementType;
|
||||
import com.intellij.psi.tree.ILightLazyParseableElementType;
|
||||
import com.intellij.psi.tree.java.IJavaElementType;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.CharTable;
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure;
|
||||
|
||||
import static com.intellij.lang.PsiBuilderUtil.expect;
|
||||
|
||||
public interface JavaElementType {
|
||||
IElementType CLASS = JavaStubElementTypes.CLASS;
|
||||
IElementType ANONYMOUS_CLASS = JavaStubElementTypes.ANONYMOUS_CLASS;
|
||||
IElementType ENUM_CONSTANT_INITIALIZER = JavaStubElementTypes.ENUM_CONSTANT_INITIALIZER;
|
||||
|
||||
IElementType TYPE_PARAMETER_LIST = JavaStubElementTypes.TYPE_PARAMETER_LIST;
|
||||
IElementType TYPE_PARAMETER = JavaStubElementTypes.TYPE_PARAMETER;
|
||||
|
||||
IElementType IMPORT_LIST = JavaStubElementTypes.IMPORT_LIST;
|
||||
IElementType IMPORT_STATEMENT = JavaStubElementTypes.IMPORT_STATEMENT;
|
||||
IElementType IMPORT_STATIC_STATEMENT = JavaStubElementTypes.IMPORT_STATIC_STATEMENT;
|
||||
|
||||
IElementType MODIFIER_LIST = JavaStubElementTypes.MODIFIER_LIST;
|
||||
IElementType ANNOTATION = JavaStubElementTypes.ANNOTATION;
|
||||
IElementType EXTENDS_LIST = JavaStubElementTypes.EXTENDS_LIST;
|
||||
IElementType IMPLEMENTS_LIST = JavaStubElementTypes.IMPLEMENTS_LIST;
|
||||
IElementType FIELD = JavaStubElementTypes.FIELD;
|
||||
IElementType ENUM_CONSTANT = JavaStubElementTypes.ENUM_CONSTANT;
|
||||
IElementType METHOD = JavaStubElementTypes.METHOD;
|
||||
IElementType ANNOTATION_METHOD = JavaStubElementTypes.ANNOTATION_METHOD;
|
||||
|
||||
IElementType CLASS_INITIALIZER = JavaStubElementTypes.CLASS_INITIALIZER;
|
||||
IElementType PARAMETER = JavaStubElementTypes.PARAMETER;
|
||||
IElementType PARAMETER_LIST = JavaStubElementTypes.PARAMETER_LIST;
|
||||
IElementType EXTENDS_BOUND_LIST = JavaStubElementTypes.EXTENDS_BOUND_LIST;
|
||||
IElementType THROWS_LIST = JavaStubElementTypes.THROWS_LIST;
|
||||
|
||||
IElementType IMPORT_STATIC_REFERENCE = new IJavaElementType("IMPORT_STATIC_REFERENCE");
|
||||
IElementType TYPE = new IJavaElementType("TYPE");
|
||||
IElementType DIAMOND_TYPE = new IJavaElementType("DIAMOND_TYPE");
|
||||
IElementType REFERENCE_PARAMETER_LIST = new IJavaElementType("REFERENCE_PARAMETER_LIST", true);
|
||||
IElementType JAVA_CODE_REFERENCE = new IJavaElementType("JAVA_CODE_REFERENCE");
|
||||
IElementType PACKAGE_STATEMENT = new IJavaElementType("PACKAGE_STATEMENT");
|
||||
|
||||
IElementType LOCAL_VARIABLE = new IJavaElementType("LOCAL_VARIABLE");
|
||||
IElementType REFERENCE_EXPRESSION = new IJavaElementType("REFERENCE_EXPRESSION");
|
||||
IElementType LITERAL_EXPRESSION = new IJavaElementType("LITERAL_EXPRESSION");
|
||||
IElementType THIS_EXPRESSION = new IJavaElementType("THIS_EXPRESSION");
|
||||
IElementType SUPER_EXPRESSION = new IJavaElementType("SUPER_EXPRESSION");
|
||||
IElementType PARENTH_EXPRESSION = new IJavaElementType("PARENTH_EXPRESSION");
|
||||
IElementType METHOD_CALL_EXPRESSION = new IJavaElementType("METHOD_CALL_EXPRESSION");
|
||||
IElementType TYPE_CAST_EXPRESSION = new IJavaElementType("TYPE_CAST_EXPRESSION");
|
||||
IElementType PREFIX_EXPRESSION = new IJavaElementType("PREFIX_EXPRESSION");
|
||||
IElementType POSTFIX_EXPRESSION = new IJavaElementType("POSTFIX_EXPRESSION");
|
||||
IElementType BINARY_EXPRESSION = new IJavaElementType("BINARY_EXPRESSION");
|
||||
IElementType CONDITIONAL_EXPRESSION = new IJavaElementType("CONDITIONAL_EXPRESSION");
|
||||
IElementType ASSIGNMENT_EXPRESSION = new IJavaElementType("ASSIGNMENT_EXPRESSION");
|
||||
IElementType NEW_EXPRESSION = new IJavaElementType("NEW_EXPRESSION");
|
||||
IElementType ARRAY_ACCESS_EXPRESSION = new IJavaElementType("ARRAY_ACCESS_EXPRESSION");
|
||||
IElementType ARRAY_INITIALIZER_EXPRESSION = new IJavaElementType("ARRAY_INITIALIZER_EXPRESSION");
|
||||
IElementType INSTANCE_OF_EXPRESSION = new IJavaElementType("INSTANCE_OF_EXPRESSION");
|
||||
IElementType CLASS_OBJECT_ACCESS_EXPRESSION = new IJavaElementType("CLASS_OBJECT_ACCESS_EXPRESSION");
|
||||
IElementType EMPTY_EXPRESSION = new IJavaElementType("EMPTY_EXPRESSION", true);
|
||||
|
||||
IElementType EXPRESSION_LIST = new IJavaElementType("EXPRESSION_LIST", true);
|
||||
|
||||
IElementType EMPTY_STATEMENT = new IJavaElementType("EMPTY_STATEMENT");
|
||||
IElementType BLOCK_STATEMENT = new IJavaElementType("BLOCK_STATEMENT");
|
||||
IElementType EXPRESSION_STATEMENT = new IJavaElementType("EXPRESSION_STATEMENT");
|
||||
IElementType EXPRESSION_LIST_STATEMENT = new IJavaElementType("EXPRESSION_LIST_STATEMENT");
|
||||
IElementType DECLARATION_STATEMENT = new IJavaElementType("DECLARATION_STATEMENT");
|
||||
IElementType IF_STATEMENT = new IJavaElementType("IF_STATEMENT");
|
||||
IElementType WHILE_STATEMENT = new IJavaElementType("WHILE_STATEMENT");
|
||||
IElementType FOR_STATEMENT = new IJavaElementType("FOR_STATEMENT");
|
||||
IElementType FOREACH_STATEMENT = new IJavaElementType("FOREACH_STATEMENT");
|
||||
IElementType DO_WHILE_STATEMENT = new IJavaElementType("DO_WHILE_STATEMENT");
|
||||
IElementType SWITCH_STATEMENT = new IJavaElementType("SWITCH_STATEMENT");
|
||||
IElementType SWITCH_LABEL_STATEMENT = new IJavaElementType("SWITCH_LABEL_STATEMENT");
|
||||
IElementType BREAK_STATEMENT = new IJavaElementType("BREAK_STATEMENT");
|
||||
IElementType CONTINUE_STATEMENT = new IJavaElementType("CONTINUE_STATEMENT");
|
||||
IElementType RETURN_STATEMENT = new IJavaElementType("RETURN_STATEMENT");
|
||||
IElementType THROW_STATEMENT = new IJavaElementType("THROW_STATEMENT");
|
||||
IElementType SYNCHRONIZED_STATEMENT = new IJavaElementType("SYNCHRONIZED_STATEMENT");
|
||||
IElementType TRY_STATEMENT = new IJavaElementType("TRY_STATEMENT");
|
||||
IElementType LABELED_STATEMENT = new IJavaElementType("LABELED_STATEMENT");
|
||||
IElementType ASSERT_STATEMENT = new IJavaElementType("ASSERT_STATEMENT");
|
||||
|
||||
IElementType CATCH_SECTION = new IJavaElementType("CATCH_SECTION");
|
||||
|
||||
IElementType ANNOTATION_ARRAY_INITIALIZER = new IJavaElementType("ANNOTATION_ARRAY_INITIALIZER");
|
||||
IElementType NAME_VALUE_PAIR = new IJavaElementType("NAME_VALUE_PAIR", true);
|
||||
IElementType ANNOTATION_PARAMETER_LIST = new IJavaElementType("ANNOTATION_PARAMETER_LIST", true);
|
||||
IElementType METHOD_RECEIVER = new IJavaElementType("METHOD_RECEIVER");
|
||||
|
||||
class ICodeBlockElementType extends IErrorCounterReparseableElementType {
|
||||
private ICodeBlockElementType() {
|
||||
super("CODE_BLOCK", StdLanguages.JAVA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode createNode(final CharSequence text) {
|
||||
return new PsiCodeBlockImpl(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
final PsiBuilder builder = JavaParserUtil.createBuilder(chameleon);
|
||||
StatementParser.parseCodeBlockDeep(builder, true);
|
||||
return builder.getTreeBuilt().getFirstChildNode();
|
||||
}
|
||||
|
||||
final CharSequence seq = chameleon.getChars();
|
||||
|
||||
ASTNode original = chameleon.getUserData(BlockSupport.TREE_TO_BE_REPARSED);
|
||||
ASTNode context = original != null ? original : chameleon.getTreeParent();
|
||||
|
||||
final PsiManager manager = context.getPsi().getManager();
|
||||
final CharTable table = SharedImplUtil.findCharTableByTree(context);
|
||||
final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(TreeUtil.getFileElement((TreeElement)context).getPsi());
|
||||
JavaParsingContext parsingContext = new JavaParsingContext(table, languageLevel);
|
||||
return parsingContext.getStatementParsing().parseCodeBlockText(manager, new JavaLexer(languageLevel),
|
||||
seq, 0, seq.length(), 0).getFirstChildNode();
|
||||
}
|
||||
|
||||
public int getErrorsCount(final CharSequence seq, final Project project) {
|
||||
final Lexer lexer = new JavaLexer(LanguageLevel.HIGHEST);
|
||||
|
||||
lexer.start(seq);
|
||||
if (lexer.getTokenType() != JavaTokenType.LBRACE) return FATAL_ERROR;
|
||||
lexer.advance();
|
||||
int balance = 1;
|
||||
while (true) {
|
||||
IElementType type = lexer.getTokenType();
|
||||
if (type == null) break;
|
||||
if (balance == 0) return FATAL_ERROR;
|
||||
if (type == JavaTokenType.LBRACE) {
|
||||
balance++;
|
||||
}
|
||||
else if (type == JavaTokenType.RBRACE) {
|
||||
balance--;
|
||||
}
|
||||
lexer.advance();
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
}
|
||||
|
||||
class ICodeBlockNewElementType extends ICodeBlockElementType implements ILightLazyParseableElementType {
|
||||
private ICodeBlockNewElementType() { }
|
||||
|
||||
public FlyweightCapableTreeStructure<LighterASTNode> parseContents(final LighterLazyParseableNode chameleon) {
|
||||
final PsiBuilder builder = JavaParserUtil.createBuilder(chameleon);
|
||||
StatementParser.parseCodeBlockDeep(builder, true);
|
||||
return builder.getLightTree();
|
||||
}
|
||||
}
|
||||
|
||||
ILazyParseableElementType CODE_BLOCK = JavaParserDefinition.USE_NEW_PARSER ? new ICodeBlockNewElementType() : new ICodeBlockElementType();
|
||||
|
||||
IElementType STATEMENTS = new ICodeFragmentElementType("STATEMENTS", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
StatementParser.parseStatements(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
final PsiManager manager = ((FileElement)chameleon).getManager();
|
||||
final CharTable table = SharedImplUtil.findCharTableByTree(chameleon);
|
||||
JavaParsingContext context = new JavaParsingContext(table, LanguageLevel.HIGHEST);
|
||||
return context.getStatementParsing().parseStatements(manager, null, chars, 0, chars.length(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
IElementType EXPRESSION_TEXT = new ICodeFragmentElementType("EXPRESSION_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ExpressionParser.parse(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
final PsiManager manager = ((FileElement)chameleon).getManager();
|
||||
final JavaParsingContext context = new JavaParsingContext(SharedImplUtil.findCharTableByTree(chameleon), LanguageLevel.HIGHEST);
|
||||
return context.getExpressionParsing().parseExpressionTextFragment(manager, chars, 0, chars.length(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
IElementType REFERENCE_TEXT = new ICodeFragmentElementType("REFERENCE_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseJavaCodeReference(builder, false, true, false, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
return Parsing.parseJavaCodeReferenceText(((FileElement)chameleon).getManager(), chars, 0, chars.length(),
|
||||
SharedImplUtil.findCharTableByTree(chameleon), true);
|
||||
}
|
||||
};
|
||||
|
||||
IElementType TYPE_TEXT = new ICodeFragmentElementType("TYPE_TEXT", StdLanguages.JAVA) {
|
||||
public ASTNode parseContents(final ASTNode chameleon) {
|
||||
if (JavaParserDefinition.USE_NEW_PARSER) {
|
||||
return JavaParserUtil.parseFragment(chameleon,
|
||||
new JavaParserUtil.ParserWrapper() {
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseType(builder, ReferenceParser.EAT_LAST_DOT | ReferenceParser.WILDCARD);
|
||||
expect(builder, JavaTokenType.ELLIPSIS); // todo[r.sh] parse ellipsis and fix PsiTypeCodeFragmentImpl.getType()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final CharSequence chars = chameleon.getChars();
|
||||
return Parsing.parseTypeText(((FileElement)chameleon).getManager(), null, chars, 0, chars.length(), 0,
|
||||
SharedImplUtil.findCharTableByTree(chameleon));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
PsiJavaFile:New15.java
|
||||
PsiMethodCallExpression:new C<?>.B()
|
||||
PsiReferenceExpression:new C<?>.B
|
||||
PsiNewExpression:new C<?>
|
||||
PsiKeyword:new('new')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaCodeReferenceElement:C<?>
|
||||
PsiIdentifier:C('C')
|
||||
PsiReferenceParameterList
|
||||
PsiJavaToken:LT('<')
|
||||
PsiTypeElement:?
|
||||
PsiJavaToken:QUEST('?')
|
||||
PsiJavaToken:GT('>')
|
||||
PsiErrorElement:'(' or '[' expected
|
||||
<empty list>
|
||||
PsiJavaToken:DOT('.')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:B('B')
|
||||
PsiExpressionList
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
+120
-119
@@ -1,119 +1,120 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.lang.java.parser.partial;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.java.parser.ExpressionParser;
|
||||
import com.intellij.lang.java.parser.JavaParsingTestCase;
|
||||
|
||||
|
||||
public class ExpressionParserTest extends JavaParsingTestCase {
|
||||
public ExpressionParserTest() {
|
||||
super("parser-partial/expressions");
|
||||
}
|
||||
|
||||
public void testAssignment0() { doParserTest("a = 0"); }
|
||||
public void testAssignment1() { doParserTest("a ="); }
|
||||
|
||||
public void testBinary0() { doParserTest("a + b"); }
|
||||
public void testBinary1() { doParserTest("a < b"); }
|
||||
|
||||
public void testCond0() { doParserTest("cond ? true : false"); }
|
||||
public void testCond1() { doParserTest("cond ?"); }
|
||||
public void testCond2() { doParserTest("cond ? true"); }
|
||||
public void testCond3() { doParserTest("cond ? true :"); }
|
||||
|
||||
public void testCondOr0() { doParserTest("a || b || c"); }
|
||||
public void testCondOr1() { doParserTest("a ||"); }
|
||||
|
||||
public void testOr0() { doParserTest("a | b | c"); }
|
||||
public void testOr1() { doParserTest("a |"); }
|
||||
|
||||
public void testInstanceOf0() { doParserTest("a instanceof String"); }
|
||||
public void testInstanceOf1() { doParserTest("a instanceof"); }
|
||||
|
||||
public void testNot0() { doParserTest("!!a"); }
|
||||
public void testNot1() { doParserTest("!"); }
|
||||
|
||||
public void testCast() { doParserTest("(Type)var"); }
|
||||
|
||||
public void testParenth0() { doParserTest("(c)"); }
|
||||
public void testParenth1() { doParserTest("(this).f--"); }
|
||||
public void testParenth2() { doParserTest("("); }
|
||||
public void testParenth3() { doParserTest("(a < b)"); }
|
||||
|
||||
public void testNewInExprList() { doParserTest("call(new)"); }
|
||||
|
||||
public void testNew0() { doParserTest("new A()"); }
|
||||
public void testNew1() { doParserTest("new A[1][]"); }
|
||||
public void testNew2() { doParserTest("new A[]"); }
|
||||
public void testNew3() { doParserTest("new A[][1]"); }
|
||||
public void testNew4() { doParserTest("new A[][]{null}"); }
|
||||
public void testNew5() { doParserTest("new A[1]{null}"); }
|
||||
public void testNew6() { doParserTest("new"); }
|
||||
public void testNew7() { doParserTest("new A"); }
|
||||
public void testNew8() { doParserTest("new A["); }
|
||||
public void testNew9() { doParserTest("new int"); }
|
||||
public void testNew10() { doParserTest("new int()"); }
|
||||
public void testNew11() { doParserTest("new String[0"); }
|
||||
public void testNew12() { doParserTest("new int[1][2]"); }
|
||||
public void testNew13() { doParserTest("new int[1][][2]"); }
|
||||
public void testNew14() { doParserTest("Q.new A()"); }
|
||||
|
||||
public void testExprList0() { doParserTest("f(1,2)"); }
|
||||
public void testExprList1() { doParserTest("f("); }
|
||||
public void testExprList2() { doParserTest("f(1"); }
|
||||
public void testExprList3() { doParserTest("f(1,"); }
|
||||
public void testExprList4() { doParserTest("f(1,)"); }
|
||||
public void testExprList5() { doParserTest("f(1,,2)"); }
|
||||
public void testExprList6() { doParserTest("f(,2)"); }
|
||||
|
||||
public void testArrayInitializer0() { doParserTest("{ }"); }
|
||||
public void testArrayInitializer1() { doParserTest("{ 1 }"); }
|
||||
public void testArrayInitializer2() { doParserTest("{ 1, }"); }
|
||||
public void testArrayInitializer3() { doParserTest("{ 1,2 }"); }
|
||||
public void testArrayInitializer4() { doParserTest("{ 1 2 }"); }
|
||||
public void testArrayInitializer5() { doParserTest("{ { }"); }
|
||||
public void testArrayInitializer6() { doParserTest("{ , }"); }
|
||||
public void testArrayInitializer7() { doParserTest("{ , , 7 }"); }
|
||||
|
||||
public void testPinesInReferenceExpression0() { doParserTest("Collections.<String>sort(null)"); }
|
||||
public void testPinesInReferenceExpression1() { doParserTest("this.<String>sort(null)"); }
|
||||
public void testPinesInReferenceExpression2() { doParserTest("<String>super(null)"); }
|
||||
|
||||
public void testGE0() { doParserTest("x >>>= 8 >> 2"); }
|
||||
public void testGE1() { doParserTest("x >= 2"); }
|
||||
|
||||
public void testIncompleteCast() { doParserTest("f((ArrayList<String>) )"); }
|
||||
public void testShiftRight() { doParserTest("x >>= 2"); }
|
||||
|
||||
public void testIllegalWildcard() { doParserTest("this.<?>foo()"); }
|
||||
|
||||
public void testQualifiedSuperMethodCall0() { doParserTest("new D().super(0)"); }
|
||||
public void testQualifiedSuperMethodCall1() { doParserTest("d.super(0)"); }
|
||||
public void testSuperMethodCallTypeParameterList() { doParserTest("super()"); }
|
||||
public void testPrimitiveClassObjectAccess() { doParserTest("int.class"); }
|
||||
public void testChainedClassObjectAccess() { doParserTest("A.class.B.class"); }
|
||||
|
||||
private void doParserTest(final String text) {
|
||||
doParserTest(text, new TestParser() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ExpressionParser.parse(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2000-2010 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.lang.java.parser.partial;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.java.parser.ExpressionParser;
|
||||
import com.intellij.lang.java.parser.JavaParsingTestCase;
|
||||
|
||||
|
||||
public class ExpressionParserTest extends JavaParsingTestCase {
|
||||
public ExpressionParserTest() {
|
||||
super("parser-partial/expressions");
|
||||
}
|
||||
|
||||
public void testAssignment0() { doParserTest("a = 0"); }
|
||||
public void testAssignment1() { doParserTest("a ="); }
|
||||
|
||||
public void testBinary0() { doParserTest("a + b"); }
|
||||
public void testBinary1() { doParserTest("a < b"); }
|
||||
|
||||
public void testCond0() { doParserTest("cond ? true : false"); }
|
||||
public void testCond1() { doParserTest("cond ?"); }
|
||||
public void testCond2() { doParserTest("cond ? true"); }
|
||||
public void testCond3() { doParserTest("cond ? true :"); }
|
||||
|
||||
public void testCondOr0() { doParserTest("a || b || c"); }
|
||||
public void testCondOr1() { doParserTest("a ||"); }
|
||||
|
||||
public void testOr0() { doParserTest("a | b | c"); }
|
||||
public void testOr1() { doParserTest("a |"); }
|
||||
|
||||
public void testInstanceOf0() { doParserTest("a instanceof String"); }
|
||||
public void testInstanceOf1() { doParserTest("a instanceof"); }
|
||||
|
||||
public void testNot0() { doParserTest("!!a"); }
|
||||
public void testNot1() { doParserTest("!"); }
|
||||
|
||||
public void testCast() { doParserTest("(Type)var"); }
|
||||
|
||||
public void testParenth0() { doParserTest("(c)"); }
|
||||
public void testParenth1() { doParserTest("(this).f--"); }
|
||||
public void testParenth2() { doParserTest("("); }
|
||||
public void testParenth3() { doParserTest("(a < b)"); }
|
||||
|
||||
public void testNewInExprList() { doParserTest("call(new)"); }
|
||||
|
||||
public void testNew0() { doParserTest("new A()"); }
|
||||
public void testNew1() { doParserTest("new A[1][]"); }
|
||||
public void testNew2() { doParserTest("new A[]"); }
|
||||
public void testNew3() { doParserTest("new A[][1]"); }
|
||||
public void testNew4() { doParserTest("new A[][]{null}"); }
|
||||
public void testNew5() { doParserTest("new A[1]{null}"); }
|
||||
public void testNew6() { doParserTest("new"); }
|
||||
public void testNew7() { doParserTest("new A"); }
|
||||
public void testNew8() { doParserTest("new A["); }
|
||||
public void testNew9() { doParserTest("new int"); }
|
||||
public void testNew10() { doParserTest("new int()"); }
|
||||
public void testNew11() { doParserTest("new String[0"); }
|
||||
public void testNew12() { doParserTest("new int[1][2]"); }
|
||||
public void testNew13() { doParserTest("new int[1][][2]"); }
|
||||
public void testNew14() { doParserTest("Q.new A()"); }
|
||||
public void testNew15() { doParserTest("new C<?>.B()"); }
|
||||
|
||||
public void testExprList0() { doParserTest("f(1,2)"); }
|
||||
public void testExprList1() { doParserTest("f("); }
|
||||
public void testExprList2() { doParserTest("f(1"); }
|
||||
public void testExprList3() { doParserTest("f(1,"); }
|
||||
public void testExprList4() { doParserTest("f(1,)"); }
|
||||
public void testExprList5() { doParserTest("f(1,,2)"); }
|
||||
public void testExprList6() { doParserTest("f(,2)"); }
|
||||
|
||||
public void testArrayInitializer0() { doParserTest("{ }"); }
|
||||
public void testArrayInitializer1() { doParserTest("{ 1 }"); }
|
||||
public void testArrayInitializer2() { doParserTest("{ 1, }"); }
|
||||
public void testArrayInitializer3() { doParserTest("{ 1,2 }"); }
|
||||
public void testArrayInitializer4() { doParserTest("{ 1 2 }"); }
|
||||
public void testArrayInitializer5() { doParserTest("{ { }"); }
|
||||
public void testArrayInitializer6() { doParserTest("{ , }"); }
|
||||
public void testArrayInitializer7() { doParserTest("{ , , 7 }"); }
|
||||
|
||||
public void testPinesInReferenceExpression0() { doParserTest("Collections.<String>sort(null)"); }
|
||||
public void testPinesInReferenceExpression1() { doParserTest("this.<String>sort(null)"); }
|
||||
public void testPinesInReferenceExpression2() { doParserTest("<String>super(null)"); }
|
||||
|
||||
public void testGE0() { doParserTest("x >>>= 8 >> 2"); }
|
||||
public void testGE1() { doParserTest("x >= 2"); }
|
||||
|
||||
public void testIncompleteCast() { doParserTest("f((ArrayList<String>) )"); }
|
||||
public void testShiftRight() { doParserTest("x >>= 2"); }
|
||||
|
||||
public void testIllegalWildcard() { doParserTest("this.<?>foo()"); }
|
||||
|
||||
public void testQualifiedSuperMethodCall0() { doParserTest("new D().super(0)"); }
|
||||
public void testQualifiedSuperMethodCall1() { doParserTest("d.super(0)"); }
|
||||
public void testSuperMethodCallTypeParameterList() { doParserTest("super()"); }
|
||||
public void testPrimitiveClassObjectAccess() { doParserTest("int.class"); }
|
||||
public void testChainedClassObjectAccess() { doParserTest("A.class.B.class"); }
|
||||
|
||||
private void doParserTest(final String text) {
|
||||
doParserTest(text, new TestParser() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ExpressionParser.parse(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+81
-81
@@ -1,81 +1,81 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.lang.java.parser.partial;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.java.parser.JavaParsingTestCase;
|
||||
import com.intellij.lang.java.parser.ReferenceParser;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
|
||||
|
||||
public class ReferenceParserTest extends JavaParsingTestCase {
|
||||
public ReferenceParserTest() {
|
||||
super("parser-partial/references");
|
||||
}
|
||||
|
||||
public void testReference0() { doRefParserTest("a", false); }
|
||||
public void testReference1() { doRefParserTest("a.", true); }
|
||||
public void testReference2() { doRefParserTest("a.b", false); }
|
||||
|
||||
public void testType0() { doTypeParserTest("int"); }
|
||||
public void testType1() { doTypeParserTest("a.b"); }
|
||||
public void testType2() { doTypeParserTest("int[]"); }
|
||||
public void testType3() { doTypeParserTest("int[]["); }
|
||||
public void testType4() { doTypeParserTest("Map<String,List<String>>"); }
|
||||
public void testType5() { doTypeParserTest("Object[]..."); }
|
||||
public void testType6() {
|
||||
withLevel(LanguageLevel.JDK_1_7,
|
||||
new Runnable() { @Override
|
||||
public void run() { doTypeParserTest("@English String @NonEmpty []"); } });
|
||||
}
|
||||
public void testType7() { doTypeParserTest("Diamond<>"); }
|
||||
|
||||
public void testTypeParams0() { doTypeParamsParserTest("<T>"); }
|
||||
public void testTypeParams1() { doTypeParamsParserTest("<T, U>"); }
|
||||
public void testTypeParams2() { doTypeParamsParserTest("<T"); }
|
||||
public void testTypeParams3() { doTypeParamsParserTest("<T hack>"); }
|
||||
public void testTypeParams4() { doTypeParamsParserTest("<T hack"); }
|
||||
public void testTypeParams5() { doTypeParamsParserTest("<T extends X & Y<Z>>"); }
|
||||
public void testTypeParams6() { doTypeParamsParserTest("<T supers X>"); }
|
||||
public void testTypeParams7() { doTypeParamsParserTest("<T extends X, Y>"); }
|
||||
|
||||
private void doRefParserTest(final String text, final boolean incomplete) {
|
||||
doParserTest(text, new TestParser() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseJavaCodeReference(builder, incomplete, false, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doTypeParserTest(final String text) {
|
||||
doParserTest(text, new TestParser() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseType(builder, ReferenceParser.DIAMONDS | ReferenceParser.ELLIPSIS);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doTypeParamsParserTest(final String text) {
|
||||
doParserTest(text, new TestParser() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseTypeParameters(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2000-2010 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.lang.java.parser.partial;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.java.parser.JavaParsingTestCase;
|
||||
import com.intellij.lang.java.parser.ReferenceParser;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
|
||||
|
||||
public class ReferenceParserTest extends JavaParsingTestCase {
|
||||
public ReferenceParserTest() {
|
||||
super("parser-partial/references");
|
||||
}
|
||||
|
||||
public void testReference0() { doRefParserTest("a", false); }
|
||||
public void testReference1() { doRefParserTest("a.", true); }
|
||||
public void testReference2() { doRefParserTest("a.b", false); }
|
||||
|
||||
public void testType0() { doTypeParserTest("int"); }
|
||||
public void testType1() { doTypeParserTest("a.b"); }
|
||||
public void testType2() { doTypeParserTest("int[]"); }
|
||||
public void testType3() { doTypeParserTest("int[]["); }
|
||||
public void testType4() { doTypeParserTest("Map<String,List<String>>"); }
|
||||
public void testType5() { doTypeParserTest("Object[]..."); }
|
||||
public void testType6() {
|
||||
withLevel(LanguageLevel.JDK_1_7,
|
||||
new Runnable() { @Override
|
||||
public void run() { doTypeParserTest("@English String @NonEmpty []"); } });
|
||||
}
|
||||
public void testType7() { doTypeParserTest("Diamond<>"); }
|
||||
|
||||
public void testTypeParams0() { doTypeParamsParserTest("<T>"); }
|
||||
public void testTypeParams1() { doTypeParamsParserTest("<T, U>"); }
|
||||
public void testTypeParams2() { doTypeParamsParserTest("<T"); }
|
||||
public void testTypeParams3() { doTypeParamsParserTest("<T hack>"); }
|
||||
public void testTypeParams4() { doTypeParamsParserTest("<T hack"); }
|
||||
public void testTypeParams5() { doTypeParamsParserTest("<T extends X & Y<Z>>"); }
|
||||
public void testTypeParams6() { doTypeParamsParserTest("<T supers X>"); }
|
||||
public void testTypeParams7() { doTypeParamsParserTest("<T extends X, Y>"); }
|
||||
|
||||
private void doRefParserTest(final String text, final boolean incomplete) {
|
||||
doParserTest(text, new TestParser() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseJavaCodeReference(builder, incomplete, false, false, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doTypeParserTest(final String text) {
|
||||
doParserTest(text, new TestParser() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseType(builder, ReferenceParser.DIAMONDS | ReferenceParser.ELLIPSIS);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doTypeParamsParserTest(final String text) {
|
||||
doParserTest(text, new TestParser() {
|
||||
@Override
|
||||
public void parse(final PsiBuilder builder) {
|
||||
ReferenceParser.parseTypeParameters(builder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user