use of org.apache.groovy.parser.antlr4.GroovyLexer.IF in project groovy by apache.
the class AstBuilder method visitClassDeclaration.
@Override
public ClassNode visitClassDeclaration(final ClassDeclarationContext ctx) {
String packageName = Optional.ofNullable(moduleNode.getPackageName()).orElse("");
String className = this.visitIdentifier(ctx.identifier());
if (VAR_STR.equals(className)) {
throw createParsingFailedException("var cannot be used for type declarations", ctx.identifier());
}
boolean isAnnotation = asBoolean(ctx.AT());
if (isAnnotation) {
if (asBoolean(ctx.typeParameters())) {
throw createParsingFailedException("annotation declaration cannot have type parameters", ctx.typeParameters());
}
if (asBoolean(ctx.EXTENDS())) {
throw createParsingFailedException("No extends clause allowed for annotation declaration", ctx.EXTENDS());
}
if (asBoolean(ctx.IMPLEMENTS())) {
throw createParsingFailedException("No implements clause allowed for annotation declaration", ctx.IMPLEMENTS());
}
}
boolean isEnum = asBoolean(ctx.ENUM());
if (isEnum) {
if (asBoolean(ctx.typeParameters())) {
throw createParsingFailedException("enum declaration cannot have type parameters", ctx.typeParameters());
}
if (asBoolean(ctx.EXTENDS())) {
throw createParsingFailedException("No extends clause allowed for enum declaration", ctx.EXTENDS());
}
}
boolean isInterface = (asBoolean(ctx.INTERFACE()) && !isAnnotation);
if (isInterface) {
if (asBoolean(ctx.IMPLEMENTS())) {
throw createParsingFailedException("No implements clause allowed for interface declaration", ctx.IMPLEMENTS());
}
}
List<ModifierNode> modifierNodeList = ctx.getNodeMetaData(TYPE_DECLARATION_MODIFIERS);
Objects.requireNonNull(modifierNodeList, "modifierNodeList should not be null");
ModifierManager modifierManager = new ModifierManager(this, modifierNodeList);
Optional<ModifierNode> finalModifierNodeOptional = modifierManager.get(FINAL);
Optional<ModifierNode> sealedModifierNodeOptional = modifierManager.get(SEALED);
Optional<ModifierNode> nonSealedModifierNodeOptional = modifierManager.get(NON_SEALED);
boolean isFinal = finalModifierNodeOptional.isPresent();
boolean isSealed = sealedModifierNodeOptional.isPresent();
boolean isNonSealed = nonSealedModifierNodeOptional.isPresent();
boolean isRecord = asBoolean(ctx.RECORD());
boolean hasRecordHeader = asBoolean(ctx.formalParameters());
if (isRecord) {
if (asBoolean(ctx.EXTENDS())) {
throw createParsingFailedException("No extends clause allowed for record declaration", ctx.EXTENDS());
}
if (!hasRecordHeader) {
throw createParsingFailedException("header declaration of record is expected", ctx.identifier());
}
if (isSealed) {
throw createParsingFailedException("`sealed` is not allowed for record declaration", sealedModifierNodeOptional.get());
}
if (isNonSealed) {
throw createParsingFailedException("`non-sealed` is not allowed for record declaration", nonSealedModifierNodeOptional.get());
}
} else {
if (hasRecordHeader) {
throw createParsingFailedException("header declaration is only allowed for record declaration", ctx.formalParameters());
}
}
if (isSealed && isNonSealed) {
throw createParsingFailedException("type cannot be defined with both `sealed` and `non-sealed`", nonSealedModifierNodeOptional.get());
}
if (isFinal && (isSealed || isNonSealed)) {
throw createParsingFailedException("type cannot be defined with both " + (isSealed ? "`sealed`" : "`non-sealed`") + " and `final`", finalModifierNodeOptional.get());
}
if ((isAnnotation || isEnum) && (isSealed || isNonSealed)) {
ModifierNode mn = isSealed ? sealedModifierNodeOptional.get() : nonSealedModifierNodeOptional.get();
throw createParsingFailedException("modifier `" + mn.getText() + "` is not allowed for " + (isEnum ? "enum" : "annotation definition"), mn);
}
boolean hasPermits = asBoolean(ctx.PERMITS());
if (!isSealed && hasPermits) {
throw createParsingFailedException("only sealed type declarations should have `permits` clause", ctx);
}
int modifiers = modifierManager.getClassModifiersOpValue();
boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
modifiers &= ~Opcodes.ACC_SYNTHETIC;
ClassNode classNode, outerClass = classNodeStack.peek();
if (isEnum) {
classNode = EnumHelper.makeEnumNode(asBoolean(outerClass) ? className : packageName + className, modifiers, null, outerClass);
} else if (asBoolean(outerClass)) {
if (outerClass.isInterface())
modifiers |= Opcodes.ACC_STATIC;
classNode = new InnerClassNode(outerClass, outerClass.getName() + "$" + className, modifiers, ClassHelper.OBJECT_TYPE.getPlainNodeReference());
} else {
classNode = new ClassNode(packageName + className, modifiers, ClassHelper.OBJECT_TYPE.getPlainNodeReference());
}
configureAST(classNode, ctx);
classNode.setSyntheticPublic(syntheticPublic);
classNode.setGenericsTypes(this.visitTypeParameters(ctx.typeParameters()));
boolean isInterfaceWithDefaultMethods = (isInterface && this.containsDefaultMethods(ctx));
if (isSealed) {
AnnotationNode sealedAnnotationNode = new AnnotationNode(ClassHelper.makeCached(Sealed.class));
if (asBoolean(ctx.ps)) {
ListExpression permittedSubclassesListExpression = listX(Arrays.stream(this.visitTypeList(ctx.ps)).map(ClassExpression::new).collect(Collectors.toList()));
sealedAnnotationNode.setMember("permittedSubclasses", permittedSubclassesListExpression);
configureAST(sealedAnnotationNode, ctx.PERMITS());
sealedAnnotationNode.setNodeMetaData("permits", true);
}
classNode.addAnnotation(sealedAnnotationNode);
} else if (isNonSealed) {
classNode.addAnnotation(new AnnotationNode(ClassHelper.makeCached(NonSealed.class)));
}
if (isInterfaceWithDefaultMethods || asBoolean(ctx.TRAIT())) {
classNode.addAnnotation(new AnnotationNode(ClassHelper.makeCached(Trait.class)));
}
if (isRecord) {
classNode.addAnnotation(new AnnotationNode(RECORD_TYPE_CLASS));
}
classNode.addAnnotations(modifierManager.getAnnotations());
if (isInterfaceWithDefaultMethods) {
classNode.putNodeMetaData(IS_INTERFACE_WITH_DEFAULT_METHODS, Boolean.TRUE);
}
classNode.putNodeMetaData(CLASS_NAME, className);
if (asBoolean(ctx.CLASS()) || asBoolean(ctx.TRAIT())) {
if (asBoolean(ctx.scs)) {
ClassNode[] scs = this.visitTypeList(ctx.scs);
if (scs.length > 1) {
throw createParsingFailedException("Cannot extend multiple classes", ctx.EXTENDS());
}
classNode.setSuperClass(scs[0]);
}
classNode.setInterfaces(this.visitTypeList(ctx.is));
this.initUsingGenerics(classNode);
} else if (isInterfaceWithDefaultMethods) {
// GROOVY-9259
classNode.setInterfaces(this.visitTypeList(ctx.scs));
this.initUsingGenerics(classNode);
} else if (isInterface) {
classNode.setModifiers(classNode.getModifiers() | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT);
classNode.setInterfaces(this.visitTypeList(ctx.scs));
this.initUsingGenerics(classNode);
this.hackMixins(classNode);
} else if (isEnum || isRecord) {
classNode.setInterfaces(this.visitTypeList(ctx.is));
this.initUsingGenerics(classNode);
if (isRecord) {
transformRecordHeaderToProperties(ctx, classNode);
}
} else if (isAnnotation) {
classNode.setModifiers(classNode.getModifiers() | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_ANNOTATION);
classNode.addInterface(ClassHelper.Annotation_TYPE);
this.hackMixins(classNode);
} else {
throw createParsingFailedException("Unsupported class declaration: " + ctx.getText(), ctx);
}
// have here to ensure it won't be the inner class
if (asBoolean(ctx.CLASS()) || asBoolean(ctx.TRAIT())) {
classNodeList.add(classNode);
}
classNodeStack.push(classNode);
ctx.classBody().putNodeMetaData(CLASS_DECLARATION_CLASS_NODE, classNode);
this.visitClassBody(ctx.classBody());
if (isRecord) {
Optional<FieldNode> fieldNodeOptional = classNode.getFields().stream().filter(f -> !isTrue(f, IS_RECORD_GENERATED) && !f.isStatic()).findFirst();
if (fieldNodeOptional.isPresent()) {
createParsingFailedException("Instance field is not allowed in `record`", fieldNodeOptional.get());
}
}
classNodeStack.pop();
if (!(asBoolean(ctx.CLASS()) || asBoolean(ctx.TRAIT()))) {
classNodeList.add(classNode);
}
groovydocManager.handle(classNode, ctx);
return classNode;
}
use of org.apache.groovy.parser.antlr4.GroovyLexer.IF in project groovy by apache.
the class AstBuilder method visitContinueStatement.
@Override
public ContinueStatement visitContinueStatement(final ContinueStatementContext ctx) {
if (visitingLoopStatementCount == 0) {
throw createParsingFailedException("continue statement is only allowed inside loops", ctx);
}
GroovyParserRuleContext gprc = switchExpressionRuleContextStack.peek();
if (gprc instanceof SwitchExpressionContext) {
throw createParsingFailedException("switch expression does not support `continue`", ctx);
}
String label = asBoolean(ctx.identifier()) ? this.visitIdentifier(ctx.identifier()) : null;
return configureAST(new ContinueStatement(label), ctx);
}
use of org.apache.groovy.parser.antlr4.GroovyLexer.IF in project groovy by apache.
the class SmartDocumentFilter method parseDocument.
private void parseDocument() throws BadLocationException {
GroovyLangLexer lexer;
try {
lexer = createLexer(styledDocument.getText(0, styledDocument.getLength()));
} catch (IOException e) {
e.printStackTrace();
this.latest = false;
return;
}
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
try {
tokenStream.fill();
} catch (LexerNoViableAltException | GroovySyntaxError e) {
// ignore
this.latest = false;
return;
} catch (Exception e) {
e.printStackTrace();
this.latest = false;
return;
}
List<Token> tokenList = tokenStream.getTokens();
List<Token> tokenListToRender;
try {
tokenListToRender = findTokensToRender(tokenList);
} finally {
this.setRenderRange(null);
}
for (Token token : tokenListToRender) {
int tokenType = token.getType();
if (EOF == tokenType) {
continue;
}
int tokenStartIndex = token.getStartIndex();
int tokenStopIndex = token.getStopIndex();
int tokenLength = tokenStopIndex - tokenStartIndex + 1;
styledDocument.setCharacterAttributes(tokenStartIndex, tokenLength, findStyleByTokenType(tokenType), true);
if (GStringBegin == tokenType || GStringPart == tokenType) {
styledDocument.setCharacterAttributes(tokenStartIndex + tokenLength - 1, 1, defaultStyle, true);
}
}
this.latestTokenList = tokenList;
this.latest = true;
}
use of org.apache.groovy.parser.antlr4.GroovyLexer.IF in project groovy by apache.
the class AstBuilder method visitCommandExpression.
@Override
public Expression visitCommandExpression(final CommandExpressionContext ctx) {
boolean hasArgumentList = asBoolean(ctx.enhancedArgumentListInPar());
boolean hasCommandArgument = asBoolean(ctx.commandArgument());
if ((hasArgumentList || hasCommandArgument) && visitingArrayInitializerCount > 0) {
// SEE http://groovy.329449.n5.nabble.com/parrot-Command-expressions-in-array-initializer-tt5752273.html
throw createParsingFailedException("Command chain expression can not be used in array initializer", ctx);
}
Expression baseExpr = (Expression) this.visit(ctx.expression());
if ((hasArgumentList || hasCommandArgument) && !isInsideParentheses(baseExpr) && baseExpr instanceof BinaryExpression && !"[".equals(((BinaryExpression) baseExpr).getOperation().getText())) {
throw createParsingFailedException("Unexpected input: '" + getOriginalText(ctx.expression()) + "'", ctx.expression());
}
MethodCallExpression methodCallExpression = null;
if (hasArgumentList) {
Expression arguments = this.visitEnhancedArgumentListInPar(ctx.enhancedArgumentListInPar());
if (baseExpr instanceof PropertyExpression) {
// e.g. obj.a 1, 2
methodCallExpression = configureAST(this.createMethodCallExpression((PropertyExpression) baseExpr, arguments), ctx.expression(), arguments);
} else if (baseExpr instanceof MethodCallExpression && !isInsideParentheses(baseExpr)) {
// e.g. m {} a, b OR m(...) a, b
if (asBoolean(arguments)) {
// The error should never be thrown.
throw new GroovyBugError("When baseExpr is a instance of MethodCallExpression, which should follow NO argumentList");
}
methodCallExpression = (MethodCallExpression) baseExpr;
} else if (!isInsideParentheses(baseExpr) && (// e.g. m 1, 2
baseExpr instanceof VariableExpression || // e.g. "$m" 1, 2
baseExpr instanceof GStringExpression || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING)))) {
// e.g. "m" 1, 2
validateInvalidMethodDefinition(baseExpr, arguments);
methodCallExpression = configureAST(this.createMethodCallExpression(baseExpr, arguments), ctx.expression(), arguments);
} else {
// e.g. a[x] b, new A() b, etc.
methodCallExpression = configureAST(this.createCallMethodCallExpression(baseExpr, arguments), ctx.expression(), arguments);
}
methodCallExpression.putNodeMetaData(IS_COMMAND_EXPRESSION, Boolean.TRUE);
if (!hasCommandArgument) {
return methodCallExpression;
}
}
if (hasCommandArgument) {
baseExpr.putNodeMetaData(IS_COMMAND_EXPRESSION, Boolean.TRUE);
}
return configureAST((Expression) ctx.commandArgument().stream().map(e -> (Object) e).reduce(methodCallExpression != null ? methodCallExpression : baseExpr, (r, e) -> {
CommandArgumentContext commandArgumentContext = (CommandArgumentContext) e;
commandArgumentContext.putNodeMetaData(CMD_EXPRESSION_BASE_EXPR, r);
return this.visitCommandArgument(commandArgumentContext);
}), ctx);
}
use of org.apache.groovy.parser.antlr4.GroovyLexer.IF in project groovy by apache.
the class AstBuilder method visitBreakStatement.
@Override
public BreakStatement visitBreakStatement(final BreakStatementContext ctx) {
if (0 == visitingLoopStatementCount && 0 == visitingSwitchStatementCount) {
throw createParsingFailedException("break statement is only allowed inside loops or switches", ctx);
}
GroovyParserRuleContext gprc = switchExpressionRuleContextStack.peek();
if (gprc instanceof SwitchExpressionContext) {
throw createParsingFailedException("switch expression does not support `break`", ctx);
}
String label = asBoolean(ctx.identifier()) ? this.visitIdentifier(ctx.identifier()) : null;
return configureAST(new BreakStatement(label), ctx);
}
Aggregations