IDEA-57347 (type parameters in new expression)

This commit is contained in:
Roman Shevchenko
2010-11-11 22:25:43 +03:00
parent 439d1455d2
commit 4bb50ef21d
8 changed files with 2545 additions and 2517 deletions
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(')')
@@ -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);
}
});
}
}
@@ -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);
}
});
}
}