Parser: added the support file annotations.
This commit is contained in:
@@ -52,6 +52,7 @@ public interface JetNodeTypes {
|
||||
|
||||
IElementType CLASS_BODY = JetStubElementTypes.CLASS_BODY;
|
||||
IElementType IMPORT_LIST = JetStubElementTypes.IMPORT_LIST;
|
||||
IElementType FILE_ANNOTATION_LIST = JetStubElementTypes.FILE_ANNOTATION_LIST;
|
||||
IElementType IMPORT_DIRECTIVE = JetStubElementTypes.IMPORT_DIRECTIVE;
|
||||
IElementType MODIFIER_LIST = JetStubElementTypes.MODIFIER_LIST;
|
||||
IElementType PRIMARY_CONSTRUCTOR_MODIFIER_LIST = JetStubElementTypes.PRIMARY_CONSTRUCTOR_MODIFIER_LIST;
|
||||
|
||||
@@ -19,14 +19,13 @@ package org.jetbrains.jet.lang.parsing;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.intellij.util.containers.Stack;
|
||||
|
||||
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
|
||||
@@ -109,8 +108,14 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
}
|
||||
|
||||
protected boolean errorAndAdvance(String message) {
|
||||
return errorAndAdvance(message, 1);
|
||||
}
|
||||
|
||||
protected boolean errorAndAdvance(String message, int advanceTokenCount) {
|
||||
PsiBuilder.Marker err = mark();
|
||||
advance(); // erroneous token
|
||||
for (int i = 0; i < advanceTokenCount; i++) {
|
||||
advance(); // erroneous token
|
||||
}
|
||||
err.error(message);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.JetNodeTypes.*;
|
||||
import static org.jetbrains.jet.lang.parsing.JetParsing.AnnotationParsingMode.REGULAR_ANNOTATIONS_ALLOW_SHORTS;
|
||||
import static org.jetbrains.jet.lang.parsing.JetParsing.AnnotationParsingMode.REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
|
||||
public class JetExpressionParsing extends AbstractJetParsing {
|
||||
@@ -339,13 +341,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
if (at(LBRACKET)) {
|
||||
if (!parseLocalDeclaration()) {
|
||||
PsiBuilder.Marker expression = mark();
|
||||
myJetParsing.parseAnnotations(false);
|
||||
myJetParsing.parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
parsePrefixExpression();
|
||||
expression.done(ANNOTATED_EXPRESSION);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
myBuilder.disableJoiningComplexTokens();
|
||||
@@ -770,7 +769,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
int valPos = matchTokenStreamPredicate(new FirstBefore(new At(VAL_KEYWORD), new AtSet(RPAR, LBRACE, RBRACE, SEMICOLON, EQ)));
|
||||
if (valPos >= 0) {
|
||||
PsiBuilder.Marker property = mark();
|
||||
myJetParsing.parseModifierList(MODIFIER_LIST, true);
|
||||
myJetParsing.parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
|
||||
myJetParsing.parseProperty(true);
|
||||
property.done(PROPERTY);
|
||||
}
|
||||
@@ -954,7 +953,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
private boolean parseLocalDeclaration() {
|
||||
PsiBuilder.Marker decl = mark();
|
||||
JetParsing.TokenDetector enumDetector = new JetParsing.TokenDetector(ENUM_KEYWORD);
|
||||
myJetParsing.parseModifierList(MODIFIER_LIST, enumDetector, false);
|
||||
myJetParsing.parseModifierList(MODIFIER_LIST, enumDetector, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
IElementType declType = parseLocalDeclarationRest(enumDetector.isDetected());
|
||||
|
||||
@@ -1200,7 +1199,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
|
||||
PsiBuilder.Marker parameter = mark();
|
||||
int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtSet(COMMA, RPAR, COLON, ARROW)));
|
||||
createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false);
|
||||
createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
expect(IDENTIFIER, "Expecting parameter declaration");
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.lang.parsing;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -28,9 +29,12 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.JetNodeTypes.*;
|
||||
import static org.jetbrains.jet.lang.parsing.JetParsing.AnnotationParsingMode.*;
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
|
||||
public class JetParsing extends AbstractJetParsing {
|
||||
private static final Logger LOG = Logger.getInstance(JetParsing.class);
|
||||
|
||||
// TODO: token sets to constants, including derived methods
|
||||
public static final Map<String, IElementType> MODIFIER_KEYWORD_MAP = new HashMap<String, IElementType>();
|
||||
static {
|
||||
@@ -167,18 +171,25 @@ public class JetParsing extends AbstractJetParsing {
|
||||
|
||||
/*
|
||||
*preamble
|
||||
* : packageDirective? import*
|
||||
* : fileAnnotationList? packageDirective? import*
|
||||
* ;
|
||||
*/
|
||||
private void parsePreamble() {
|
||||
PsiBuilder.Marker firstEntry = mark();
|
||||
|
||||
/*
|
||||
* fileAnnotationList
|
||||
* : fileAnnotations*
|
||||
*/
|
||||
parseFileAnnotationList(FILE_ANNOTATIONS_BEFORE_PACKAGE);
|
||||
|
||||
/*
|
||||
* packageDirective
|
||||
* : modifiers "package" SimpleName{"."} SEMI?
|
||||
* ;
|
||||
*/
|
||||
PsiBuilder.Marker packageDirective = mark();
|
||||
PsiBuilder.Marker firstEntry = mark();
|
||||
parseModifierList(MODIFIER_LIST, true);
|
||||
parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
|
||||
|
||||
if (at(PACKAGE_KEYWORD)) {
|
||||
advance(); // PACKAGE_KEYWORD
|
||||
@@ -188,7 +199,11 @@ public class JetParsing extends AbstractJetParsing {
|
||||
|
||||
if (at(LBRACE)) {
|
||||
// Because it's blocked package and it will be parsed as one of top level objects
|
||||
packageDirective.drop();
|
||||
firstEntry.rollbackTo();
|
||||
|
||||
parseFileAnnotationList(/*reportErrorForNonFileAnnotations =*/ false);
|
||||
packageDirective = mark();
|
||||
packageDirective.done(PACKAGE_DIRECTIVE);
|
||||
return;
|
||||
}
|
||||
@@ -198,7 +213,12 @@ public class JetParsing extends AbstractJetParsing {
|
||||
consumeIf(SEMICOLON);
|
||||
}
|
||||
else {
|
||||
// When package directive is omitted we should not report error on non-file annotations at the beginning of the file.
|
||||
// So, we rollback the parsing position and reparse file annotation list without report error on non-file annotations.
|
||||
firstEntry.rollbackTo();
|
||||
|
||||
parseFileAnnotationList(FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED);
|
||||
packageDirective = mark();
|
||||
}
|
||||
packageDirective.done(PACKAGE_DIRECTIVE);
|
||||
|
||||
@@ -342,7 +362,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
PsiBuilder.Marker decl = mark();
|
||||
|
||||
TokenDetector detector = new TokenDetector(ENUM_KEYWORD);
|
||||
parseModifierList(MODIFIER_LIST, detector, true);
|
||||
parseModifierList(MODIFIER_LIST, detector, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
|
||||
|
||||
IElementType keywordToken = tt();
|
||||
IElementType declType = null;
|
||||
@@ -379,8 +399,11 @@ public class JetParsing extends AbstractJetParsing {
|
||||
/*
|
||||
* (modifier | attribute)*
|
||||
*/
|
||||
boolean parseModifierList(IElementType nodeType, boolean allowShortAnnotations) {
|
||||
return parseModifierList(nodeType, null, allowShortAnnotations);
|
||||
boolean parseModifierList(
|
||||
@NotNull IElementType nodeType,
|
||||
@NotNull AnnotationParsingMode annotationParsingMode
|
||||
) {
|
||||
return parseModifierList(nodeType, null, annotationParsingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -388,7 +411,11 @@ public class JetParsing extends AbstractJetParsing {
|
||||
*
|
||||
* Feeds modifiers (not attributes) into the passed consumer, if it is not null
|
||||
*/
|
||||
boolean parseModifierList(IElementType nodeType, @Nullable Consumer<IElementType> tokenConsumer, boolean allowShortAnnotations) {
|
||||
boolean parseModifierList(
|
||||
@NotNull IElementType nodeType,
|
||||
@Nullable Consumer<IElementType> tokenConsumer,
|
||||
@NotNull AnnotationParsingMode annotationParsingMode
|
||||
) {
|
||||
PsiBuilder.Marker list = mark();
|
||||
boolean empty = true;
|
||||
while (!eof()) {
|
||||
@@ -396,8 +423,8 @@ public class JetParsing extends AbstractJetParsing {
|
||||
if (tokenConsumer != null) tokenConsumer.consume(tt());
|
||||
advance(); // MODIFIER
|
||||
}
|
||||
else if (at(LBRACKET) || (allowShortAnnotations && at(IDENTIFIER))) {
|
||||
parseAnnotation(allowShortAnnotations);
|
||||
else if (at(LBRACKET) || (annotationParsingMode.allowShortAnnotations && at(IDENTIFIER))) {
|
||||
parseAnnotation(annotationParsingMode);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@@ -414,29 +441,68 @@ public class JetParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
/*
|
||||
* annotations
|
||||
* : annotation*
|
||||
* fileAnnotationList
|
||||
* : ("[" "file:" annotationEntry+ "]")*
|
||||
* ;
|
||||
*/
|
||||
void parseAnnotations(boolean allowShortAnnotations) {
|
||||
while (true) {
|
||||
if (!(parseAnnotation(allowShortAnnotations))) break;
|
||||
private void parseFileAnnotationList(AnnotationParsingMode mode) {
|
||||
if (!mode.isFileAnnotationParsingMode) {
|
||||
LOG.error("expected file annotation parsing mode, but:" + mode);
|
||||
}
|
||||
|
||||
PsiBuilder.Marker fileAnnotationsList = mark();
|
||||
|
||||
if (parseAnnotations(mode)) {
|
||||
fileAnnotationsList.done(FILE_ANNOTATION_LIST);
|
||||
}
|
||||
else {
|
||||
fileAnnotationsList.drop();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* annotations
|
||||
* : annotation*
|
||||
* ;
|
||||
*/
|
||||
boolean parseAnnotations(AnnotationParsingMode mode) {
|
||||
if (!parseAnnotation(mode)) return false;
|
||||
|
||||
while (parseAnnotation(mode)) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* annotation
|
||||
* : "[" annotationEntry+ "]"
|
||||
* : "[" ("file" ":")? annotationEntry+ "]"
|
||||
* : annotationEntry
|
||||
* ;
|
||||
*/
|
||||
private boolean parseAnnotation(boolean allowShortAnnotations) {
|
||||
private boolean parseAnnotation(AnnotationParsingMode mode) {
|
||||
if (at(LBRACKET)) {
|
||||
PsiBuilder.Marker annotation = mark();
|
||||
|
||||
myBuilder.disableNewlines();
|
||||
advance(); // LBRACKET
|
||||
|
||||
if (mode.isFileAnnotationParsingMode) {
|
||||
if (mode == FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED && !(at(FILE_KEYWORD) && lookahead(1) == COLON)) {
|
||||
annotation.rollbackTo();
|
||||
myBuilder.restoreNewlinesState();
|
||||
return false;
|
||||
}
|
||||
|
||||
String message = "Expecting \"" + FILE_KEYWORD.getValue() + COLON.getValue() + "\" prefix for file annotations";
|
||||
expect(FILE_KEYWORD, message);
|
||||
expect(COLON, message, TokenSet.create(IDENTIFIER, RBRACKET));
|
||||
}
|
||||
else if (at(FILE_KEYWORD) && lookahead(1) == COLON) {
|
||||
errorAndAdvance("File annotations are only allowed before package declaration", 2);
|
||||
}
|
||||
|
||||
if (!at(IDENTIFIER)) {
|
||||
error("Expecting a list of attributes");
|
||||
}
|
||||
@@ -460,10 +526,11 @@ public class JetParsing extends AbstractJetParsing {
|
||||
annotation.done(ANNOTATION);
|
||||
return true;
|
||||
}
|
||||
else if (allowShortAnnotations && at(IDENTIFIER)) {
|
||||
else if (mode.allowShortAnnotations && at(IDENTIFIER)) {
|
||||
parseAnnotationEntry();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -509,7 +576,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
|
||||
|
||||
PsiBuilder.Marker beforeConstructorModifiers = mark();
|
||||
boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, false);
|
||||
boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
// Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
|
||||
if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON) ) {
|
||||
@@ -569,7 +636,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
TokenSet constructorNameFollow = TokenSet.create(SEMICOLON, COLON, LPAR, LT, LBRACE);
|
||||
int lastId = findLastBefore(ENUM_MEMBER_FIRST, constructorNameFollow, false);
|
||||
TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
|
||||
createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST, enumDetector, false);
|
||||
createTruncatedBuilder(lastId).parseModifierList(MODIFIER_LIST, enumDetector, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
IElementType type;
|
||||
if (at(IDENTIFIER)) {
|
||||
@@ -666,7 +733,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
PsiBuilder.Marker decl = mark();
|
||||
|
||||
TokenDetector enumDetector = new TokenDetector(ENUM_KEYWORD);
|
||||
parseModifierList(MODIFIER_LIST, enumDetector, true);
|
||||
parseModifierList(MODIFIER_LIST, enumDetector, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
|
||||
|
||||
IElementType declType = parseMemberDeclarationRest(enumDetector.isDetected());
|
||||
|
||||
@@ -777,7 +844,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
*/
|
||||
private void parseInitializer() {
|
||||
PsiBuilder.Marker initializer = mark();
|
||||
parseAnnotations(false);
|
||||
parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
IElementType type;
|
||||
if (at(THIS_KEYWORD)) {
|
||||
@@ -1020,7 +1087,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
private boolean parsePropertyGetterOrSetter() {
|
||||
PsiBuilder.Marker getterOrSetter = mark();
|
||||
|
||||
parseModifierList(MODIFIER_LIST, false);
|
||||
parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
if (!at(GET_KEYWORD) && !at(SET_KEYWORD)) {
|
||||
getterOrSetter.rollbackTo();
|
||||
@@ -1150,7 +1217,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
*/
|
||||
private void parseReceiverType(String title, TokenSet nameFollow, int lastDot) {
|
||||
if (lastDot == -1) { // There's no explicit receiver type specified
|
||||
parseAnnotations(false);
|
||||
parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
}
|
||||
else {
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
@@ -1249,7 +1316,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
*/
|
||||
private void parseDelegationSpecifier() {
|
||||
PsiBuilder.Marker delegator = mark();
|
||||
parseAnnotations(false);
|
||||
parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
PsiBuilder.Marker reference = mark();
|
||||
parseTypeRef();
|
||||
@@ -1349,7 +1416,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
private void parseTypeConstraint() {
|
||||
PsiBuilder.Marker constraint = mark();
|
||||
|
||||
parseAnnotations(false);
|
||||
parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
if (at(CLASS_KEYWORD)) {
|
||||
advance(); // CLASS_KEYWORD
|
||||
@@ -1431,7 +1498,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
// we don't support this case now
|
||||
// myBuilder.disableJoiningComplexTokens();
|
||||
PsiBuilder.Marker typeRefMarker = mark();
|
||||
parseAnnotations(false);
|
||||
parseAnnotations(REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
if (at(IDENTIFIER) || at(PACKAGE_KEYWORD)) {
|
||||
parseUserType();
|
||||
@@ -1533,7 +1600,8 @@ public class JetParsing extends AbstractJetParsing {
|
||||
|
||||
PsiBuilder.Marker reference = mark();
|
||||
while (true) {
|
||||
if (expect(IDENTIFIER, "Expecting type name", TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW))) {
|
||||
if (expect(IDENTIFIER, "Expecting type name",
|
||||
TokenSet.orSet(JetExpressionParsing.EXPRESSION_FIRST, JetExpressionParsing.EXPRESSION_FOLLOW))) {
|
||||
reference.done(REFERENCE_EXPRESSION);
|
||||
}
|
||||
else {
|
||||
@@ -1600,7 +1668,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
// TokenSet stopAt = TokenSet.create(COMMA, COLON, GT);
|
||||
// parseModifierListWithShortAnnotations(MODIFIER_LIST, lookFor, stopAt);
|
||||
// Currently we do not allow annotations
|
||||
parseModifierList(MODIFIER_LIST, false);
|
||||
parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS);
|
||||
|
||||
if (at(MUL)) {
|
||||
advance(); // MUL
|
||||
@@ -1626,7 +1694,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
|
||||
private void parseModifierListWithShortAnnotations(IElementType modifierList, TokenSet lookFor, TokenSet stopAt) {
|
||||
int lastId = findLastBefore(lookFor, stopAt, false);
|
||||
createTruncatedBuilder(lastId).parseModifierList(modifierList, true);
|
||||
createTruncatedBuilder(lastId).parseModifierList(modifierList, REGULAR_ANNOTATIONS_ALLOW_SHORTS);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1741,7 +1809,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
if (isFunctionTypeContents) {
|
||||
if (!tryParseValueParameter()) {
|
||||
PsiBuilder.Marker valueParameter = mark();
|
||||
parseModifierList(MODIFIER_LIST, false); // lazy, out, ref
|
||||
parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS); // lazy, out, ref
|
||||
parseTypeRef();
|
||||
valueParameter.done(VALUE_PARAMETER);
|
||||
}
|
||||
@@ -1857,4 +1925,19 @@ public class JetParsing extends AbstractJetParsing {
|
||||
return detected;
|
||||
}
|
||||
}
|
||||
|
||||
static enum AnnotationParsingMode {
|
||||
FILE_ANNOTATIONS_BEFORE_PACKAGE(false, true),
|
||||
FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(false, true),
|
||||
REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS(false, false),
|
||||
REGULAR_ANNOTATIONS_ALLOW_SHORTS(true, false);
|
||||
|
||||
boolean allowShortAnnotations;
|
||||
boolean isFileAnnotationParsingMode;
|
||||
|
||||
AnnotationParsingMode(boolean allowShortAnnotations, boolean onlyFileAnnotations) {
|
||||
this.allowShortAnnotations = allowShortAnnotations;
|
||||
this.isFileAnnotationParsingMode = onlyFileAnnotations;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
import org.jetbrains.jet.lang.psi.stubs.PsiJetFileStub;
|
||||
import org.jetbrains.jet.lang.psi.stubs.elements.JetPlaceHolderStubElementType;
|
||||
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.plugin.JetFileType;
|
||||
@@ -39,7 +40,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class JetFile extends PsiFileBase implements JetDeclarationContainer, JetElement, PsiClassOwner {
|
||||
public class JetFile extends PsiFileBase implements JetDeclarationContainer, JetAnnotated, JetElement, PsiClassOwner {
|
||||
|
||||
private final boolean isCompiled;
|
||||
|
||||
@@ -80,12 +81,25 @@ public class JetFile extends PsiFileBase implements JetDeclarationContainer, Jet
|
||||
|
||||
@Nullable
|
||||
public JetImportList getImportList() {
|
||||
return findChildByTypeOrClass(JetStubElementTypes.IMPORT_LIST, JetImportList.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetFileAnnotationList getFileAnnotationList() {
|
||||
return findChildByTypeOrClass(JetStubElementTypes.FILE_ANNOTATION_LIST, JetFileAnnotationList.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T extends JetElementImplStub<? extends StubElement<?>>> T findChildByTypeOrClass(
|
||||
@NotNull JetPlaceHolderStubElementType<T> elementType,
|
||||
@NotNull Class<T> elementClass
|
||||
) {
|
||||
PsiJetFileStub stub = getStub();
|
||||
if (stub != null) {
|
||||
StubElement<JetImportList> importListStub = stub.findChildStubByType(JetStubElementTypes.IMPORT_LIST);
|
||||
StubElement<T> importListStub = stub.findChildStubByType(elementType);
|
||||
return importListStub != null ? importListStub.getPsi() : null;
|
||||
}
|
||||
return findChildByClass(JetImportList.class);
|
||||
return findChildByClass(elementClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -205,4 +219,22 @@ public class JetFile extends PsiFileBase implements JetDeclarationContainer, Jet
|
||||
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitJetFile(this, data);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetAnnotation> getAnnotations() {
|
||||
JetFileAnnotationList fileAnnotationList = getFileAnnotationList();
|
||||
if (fileAnnotationList == null) return Collections.emptyList();
|
||||
|
||||
return fileAnnotationList.getAnnotations();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JetAnnotationEntry> getAnnotationEntries() {
|
||||
JetFileAnnotationList fileAnnotationList = getFileAnnotationList();
|
||||
if (fileAnnotationList == null) return Collections.emptyList();
|
||||
|
||||
return fileAnnotationList.getAnnotationEntries();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import kotlin.Function1;
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.stubs.PsiJetPlaceHolderStub;
|
||||
import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JetFileAnnotationList extends JetElementImplStub<PsiJetPlaceHolderStub<JetFileAnnotationList>> {
|
||||
|
||||
public JetFileAnnotationList(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public JetFileAnnotationList(@NotNull PsiJetPlaceHolderStub<JetFileAnnotationList> stub) {
|
||||
super(stub, JetStubElementTypes.FILE_ANNOTATION_LIST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitFileAnnotationList(this, data);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JetAnnotation> getAnnotations() {
|
||||
return getStubOrPsiChildrenAsList(JetStubElementTypes.ANNOTATION);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<JetAnnotationEntry> getAnnotationEntries() {
|
||||
return KotlinPackage.flatMap(getAnnotations(), new Function1<JetAnnotation, List<JetAnnotationEntry>>() {
|
||||
@Override
|
||||
public List<JetAnnotationEntry> invoke(JetAnnotation annotation) {
|
||||
return annotation.getEntries();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,10 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
|
||||
return visitJetElement(importList, data);
|
||||
}
|
||||
|
||||
public R visitFileAnnotationList(@NotNull JetFileAnnotationList fileAnnotationList, D data) {
|
||||
return visitJetElement(fileAnnotationList, data);
|
||||
}
|
||||
|
||||
public R visitClassBody(@NotNull JetClassBody classBody, D data) {
|
||||
return visitJetElement(classBody, data);
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import org.jetbrains.jet.plugin.JetLanguage;
|
||||
import java.io.IOException;
|
||||
|
||||
public class JetFileElementType extends IStubFileElementType<PsiJetFileStub> {
|
||||
public static final int STUB_VERSION = 29;
|
||||
public static final int STUB_VERSION = 30;
|
||||
|
||||
public JetFileElementType() {
|
||||
super("jet.FILE", JetLanguage.INSTANCE);
|
||||
|
||||
+3
@@ -52,6 +52,9 @@ public interface JetStubElementTypes {
|
||||
JetPlaceHolderStubElementType<JetImportList> IMPORT_LIST =
|
||||
new JetPlaceHolderStubElementType<JetImportList>("IMPORT_LIST", JetImportList.class);
|
||||
|
||||
JetPlaceHolderStubElementType<JetFileAnnotationList> FILE_ANNOTATION_LIST =
|
||||
new JetPlaceHolderStubElementType<JetFileAnnotationList>("FILE_ANNOTATION_LIST", JetFileAnnotationList.class);
|
||||
|
||||
JetImportDirectiveElementType IMPORT_DIRECTIVE = new JetImportDirectiveElementType("IMPORT_DIRECTIVE");
|
||||
|
||||
JetPlaceHolderStubElementType<JetPackageDirective> PACKAGE_DIRECTIVE =
|
||||
|
||||
@@ -131,6 +131,7 @@ public interface JetTokens {
|
||||
JetSingleValueToken COMMA = new JetSingleValueToken("COMMA", ",");
|
||||
|
||||
JetToken EOL_OR_SEMICOLON = new JetToken("EOL_OR_SEMICOLON");
|
||||
JetKeywordToken FILE_KEYWORD = JetKeywordToken.softKeyword("file");
|
||||
JetKeywordToken IMPORT_KEYWORD = JetKeywordToken.softKeyword("import");
|
||||
JetKeywordToken WHERE_KEYWORD = JetKeywordToken.softKeyword("where");
|
||||
JetKeywordToken BY_KEYWORD = JetKeywordToken.softKeyword("by");
|
||||
@@ -163,7 +164,7 @@ public interface JetTokens {
|
||||
NOT_IN, NOT_IS, CAPITALIZED_THIS_KEYWORD, AS_SAFE
|
||||
);
|
||||
|
||||
TokenSet SOFT_KEYWORDS = TokenSet.create(IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, GET_KEYWORD,
|
||||
TokenSet SOFT_KEYWORDS = TokenSet.create(FILE_KEYWORD, IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, GET_KEYWORD,
|
||||
SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD,
|
||||
OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD,
|
||||
CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, REIFIED_KEYWORD
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package bar
|
||||
|
||||
[file: foo]
|
||||
val prop
|
||||
|
||||
[file:bar baz]
|
||||
fun func() {}
|
||||
|
||||
[file:baz]
|
||||
class C
|
||||
|
||||
[file:]
|
||||
trait T
|
||||
@@ -0,0 +1,93 @@
|
||||
JetFile: fileAnnotationInWrongPlace.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n\n')
|
||||
PROPERTY
|
||||
MODIFIER_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:File annotations are only allowed before package declaration
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('prop')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
MODIFIER_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:File annotations are only allowed before package declaration
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('baz')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('func')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:File annotations are only allowed before package declaration
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('baz')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('C')
|
||||
PsiWhiteSpace('\n\n')
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:File annotations are only allowed before package declaration
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiErrorElement:Expecting a list of attributes
|
||||
<empty list>
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(trait)('trait')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('T')
|
||||
@@ -0,0 +1,3 @@
|
||||
[file: foo]
|
||||
[file:bar baz]
|
||||
package bar
|
||||
@@ -0,0 +1,39 @@
|
||||
JetFile: manyAnnotationBlocks.kt
|
||||
FILE_ANNOTATION_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('baz')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
@@ -0,0 +1,3 @@
|
||||
[file: foo bar
|
||||
baz]
|
||||
package bar
|
||||
@@ -0,0 +1,34 @@
|
||||
JetFile: manyInOneAnnotationBlock.kt
|
||||
FILE_ANNOTATION_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('baz')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
@@ -0,0 +1,8 @@
|
||||
[foo]
|
||||
[file bar]
|
||||
[file, baz]
|
||||
[file]
|
||||
[:foo.bar]
|
||||
[file:]
|
||||
[:]
|
||||
package boo
|
||||
@@ -0,0 +1,88 @@
|
||||
JetFile: nonFIleAnnotationBeforePackage.kt
|
||||
FILE_ANNOTATION_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:Expecting "file:" prefix for file annotations
|
||||
<empty list>
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiErrorElement:Expecting "file:" prefix for file annotations
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiErrorElement:Expecting "file:" prefix for file annotations
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('baz')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiErrorElement:Expecting "file:" prefix for file annotations
|
||||
<empty list>
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:Expecting "file:" prefix for file annotations
|
||||
<empty list>
|
||||
PsiElement(COLON)(':')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiErrorElement:Expecting a list of annotations
|
||||
<empty list>
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:Expecting "file:" prefix for file annotations
|
||||
<empty list>
|
||||
PsiElement(COLON)(':')
|
||||
PsiErrorElement:Expecting a list of annotations
|
||||
<empty list>
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('boo')
|
||||
@@ -0,0 +1,2 @@
|
||||
[file: foo]
|
||||
package bar
|
||||
@@ -0,0 +1,20 @@
|
||||
JetFile: single.kt
|
||||
FILE_ANNOTATION_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
@@ -0,0 +1,3 @@
|
||||
[ann] fun foo(): String? = null
|
||||
|
||||
annotation class ann
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
JetFile: withoutFileAnnotationAndPackageDeclaration.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
FUN
|
||||
MODIFIER_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('String')
|
||||
PsiElement(QUEST)('?')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
NULL
|
||||
PsiElement(null)('null')
|
||||
PsiWhiteSpace('\n\n')
|
||||
CLASS
|
||||
MODIFIER_LIST
|
||||
PsiElement(annotation)('annotation')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(class)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('ann')
|
||||
@@ -0,0 +1,4 @@
|
||||
[file: foo]
|
||||
[foo bar]
|
||||
[file: baz]
|
||||
fun foo() {}
|
||||
@@ -0,0 +1,60 @@
|
||||
JetFile: withoutPackage.kt
|
||||
FILE_ANNOTATION_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
FUN
|
||||
MODIFIER_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:File annotations are only allowed before package declaration
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('baz')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -0,0 +1,4 @@
|
||||
[file: foo]
|
||||
foo bar
|
||||
[file: baz]
|
||||
fun foo() {}
|
||||
@@ -0,0 +1,57 @@
|
||||
JetFile: withoutPackageWithSimpleAnnotation.kt
|
||||
FILE_ANNOTATION_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
FUN
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiErrorElement:File annotations are only allowed before package declaration
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('baz')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -0,0 +1,3 @@
|
||||
[file: foo]
|
||||
[file:bar baz]
|
||||
package bar
|
||||
@@ -0,0 +1,42 @@
|
||||
JetFile: manyAnnotationsOnFile.kts
|
||||
FILE_ANNOTATION_LIST
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
ANNOTATION
|
||||
PsiElement(LBRACKET)('[')
|
||||
PsiElement(file)('file')
|
||||
PsiElement(COLON)(':')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiWhiteSpace(' ')
|
||||
ANNOTATION_ENTRY
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('baz')
|
||||
PsiElement(RBRACKET)(']')
|
||||
PsiWhiteSpace('\n')
|
||||
PACKAGE_DIRECTIVE
|
||||
PsiElement(package)('package')
|
||||
PsiWhiteSpace(' ')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
SCRIPT
|
||||
BLOCK
|
||||
<empty list>
|
||||
@@ -35,7 +35,7 @@ import java.util.regex.Pattern;
|
||||
public class JetParsingTestGenerated extends AbstractJetParsingTest {
|
||||
@TestMetadata("compiler/testData/psi")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({Psi.Examples.class, Psi.FunctionReceivers.class, Psi.GreatSyntacticShift.class, Psi.Kdoc.class, Psi.PropertyDelegate.class, Psi.Recovery.class, Psi.Script.class, Psi.StringTemplates.class})
|
||||
@InnerTestClasses({Psi.Annotation.class, Psi.Examples.class, Psi.FunctionReceivers.class, Psi.GreatSyntacticShift.class, Psi.Kdoc.class, Psi.PropertyDelegate.class, Psi.Recovery.class, Psi.Script.class, Psi.StringTemplates.class})
|
||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||
public static class Psi extends AbstractJetParsingTest {
|
||||
@TestMetadata("AbsentInnerType.kt")
|
||||
@@ -546,6 +546,75 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/annotation")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({Annotation.OnFile.class})
|
||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||
public static class Annotation extends AbstractJetParsingTest {
|
||||
public void testAllFilesPresentInAnnotation() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/annotation"), Pattern.compile("^(.*)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/annotation/onFile")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||
public static class OnFile extends AbstractJetParsingTest {
|
||||
public void testAllFilesPresentInOnFile() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/annotation/onFile"), Pattern.compile("^(.*)\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("fileAnnotationInWrongPlace.kt")
|
||||
public void testFileAnnotationInWrongPlace() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/annotation/onFile/fileAnnotationInWrongPlace.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("manyAnnotationBlocks.kt")
|
||||
public void testManyAnnotationBlocks() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/annotation/onFile/manyAnnotationBlocks.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("manyInOneAnnotationBlock.kt")
|
||||
public void testManyInOneAnnotationBlock() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/annotation/onFile/manyInOneAnnotationBlock.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nonFIleAnnotationBeforePackage.kt")
|
||||
public void testNonFIleAnnotationBeforePackage() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/annotation/onFile/nonFIleAnnotationBeforePackage.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("single.kt")
|
||||
public void testSingle() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/annotation/onFile/single.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withoutFileAnnotationAndPackageDeclaration.kt")
|
||||
public void testWithoutFileAnnotationAndPackageDeclaration() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/annotation/onFile/withoutFileAnnotationAndPackageDeclaration.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withoutPackage.kt")
|
||||
public void testWithoutPackage() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/annotation/onFile/withoutPackage.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withoutPackageWithSimpleAnnotation.kt")
|
||||
public void testWithoutPackageWithSimpleAnnotation() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/annotation/onFile/withoutPackageWithSimpleAnnotation.kt");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/examples")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({Examples.Array.class, Examples.Collections.class, Examples.Io.class, Examples.Map.class, Examples.Priorityqueues.class, Examples.Util.class})
|
||||
@@ -1251,6 +1320,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("manyAnnotationsOnFile.kts")
|
||||
public void testManyAnnotationsOnFile() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/script/manyAnnotationsOnFile.kts");
|
||||
doParsingTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Shebang.kts")
|
||||
public void testShebang() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/script/Shebang.kts");
|
||||
|
||||
Reference in New Issue
Block a user