use of org.codehaus.groovy.syntax.SyntaxException in project groovy-core by groovy.
the class BindableASTTransformation method addListenerToProperty.
private void addListenerToProperty(SourceUnit source, AnnotationNode node, ClassNode declaringClass, FieldNode field) {
String fieldName = field.getName();
for (PropertyNode propertyNode : declaringClass.getProperties()) {
if (propertyNode.getName().equals(fieldName)) {
if (field.isStatic()) {
// noinspection ThrowableInstanceNeverThrown
source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Bindable cannot annotate a static property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
} else {
if (needsPropertyChangeSupport(declaringClass, source)) {
addPropertyChangeSupport(declaringClass);
}
createListenerSetter(declaringClass, propertyNode);
}
return;
}
}
// noinspection ThrowableInstanceNeverThrown
source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Bindable must be on a property, not a field. Try removing the private, protected, or public modifier.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
}
use of org.codehaus.groovy.syntax.SyntaxException in project groovy-core by groovy.
the class BinaryExpressionHelper method eval.
public void eval(BinaryExpression expression) {
switch(expression.getOperation().getType()) {
case // = assignment
EQUAL:
evaluateEqual(expression, false);
break;
case // ==
COMPARE_EQUAL:
evaluateCompareExpression(compareEqualMethod, expression);
break;
case COMPARE_NOT_EQUAL:
evaluateCompareExpression(compareNotEqualMethod, expression);
break;
case COMPARE_TO:
evaluateCompareTo(expression);
break;
case COMPARE_GREATER_THAN:
evaluateCompareExpression(compareGreaterThanMethod, expression);
break;
case COMPARE_GREATER_THAN_EQUAL:
evaluateCompareExpression(compareGreaterThanEqualMethod, expression);
break;
case COMPARE_LESS_THAN:
evaluateCompareExpression(compareLessThanMethod, expression);
break;
case COMPARE_LESS_THAN_EQUAL:
evaluateCompareExpression(compareLessThanEqualMethod, expression);
break;
case LOGICAL_AND:
evaluateLogicalAndExpression(expression);
break;
case LOGICAL_OR:
evaluateLogicalOrExpression(expression);
break;
case BITWISE_AND:
evaluateBinaryExpression("and", expression);
break;
case BITWISE_AND_EQUAL:
evaluateBinaryExpressionWithAssignment("and", expression);
break;
case BITWISE_OR:
evaluateBinaryExpression("or", expression);
break;
case BITWISE_OR_EQUAL:
evaluateBinaryExpressionWithAssignment("or", expression);
break;
case BITWISE_XOR:
evaluateBinaryExpression("xor", expression);
break;
case BITWISE_XOR_EQUAL:
evaluateBinaryExpressionWithAssignment("xor", expression);
break;
case PLUS:
evaluateBinaryExpression("plus", expression);
break;
case PLUS_EQUAL:
evaluateBinaryExpressionWithAssignment("plus", expression);
break;
case MINUS:
evaluateBinaryExpression("minus", expression);
break;
case MINUS_EQUAL:
evaluateBinaryExpressionWithAssignment("minus", expression);
break;
case MULTIPLY:
evaluateBinaryExpression("multiply", expression);
break;
case MULTIPLY_EQUAL:
evaluateBinaryExpressionWithAssignment("multiply", expression);
break;
case DIVIDE:
evaluateBinaryExpression("div", expression);
break;
case DIVIDE_EQUAL:
// SPG don't use divide since BigInteger implements directly
// and we want to dispatch through DefaultGroovyMethods to get a BigDecimal result
evaluateBinaryExpressionWithAssignment("div", expression);
break;
case INTDIV:
evaluateBinaryExpression("intdiv", expression);
break;
case INTDIV_EQUAL:
evaluateBinaryExpressionWithAssignment("intdiv", expression);
break;
case MOD:
evaluateBinaryExpression("mod", expression);
break;
case MOD_EQUAL:
evaluateBinaryExpressionWithAssignment("mod", expression);
break;
case POWER:
evaluateBinaryExpression("power", expression);
break;
case POWER_EQUAL:
evaluateBinaryExpressionWithAssignment("power", expression);
break;
case LEFT_SHIFT:
evaluateBinaryExpression("leftShift", expression);
break;
case LEFT_SHIFT_EQUAL:
evaluateBinaryExpressionWithAssignment("leftShift", expression);
break;
case RIGHT_SHIFT:
evaluateBinaryExpression("rightShift", expression);
break;
case RIGHT_SHIFT_EQUAL:
evaluateBinaryExpressionWithAssignment("rightShift", expression);
break;
case RIGHT_SHIFT_UNSIGNED:
evaluateBinaryExpression("rightShiftUnsigned", expression);
break;
case RIGHT_SHIFT_UNSIGNED_EQUAL:
evaluateBinaryExpressionWithAssignment("rightShiftUnsigned", expression);
break;
case KEYWORD_INSTANCEOF:
evaluateInstanceof(expression);
break;
case FIND_REGEX:
evaluateCompareExpression(findRegexMethod, expression);
break;
case MATCH_REGEX:
evaluateCompareExpression(matchRegexMethod, expression);
break;
case LEFT_SQUARE_BRACKET:
if (controller.getCompileStack().isLHS()) {
evaluateEqual(expression, false);
} else {
evaluateBinaryExpression("getAt", expression);
}
break;
case KEYWORD_IN:
evaluateCompareExpression(isCaseMethod, expression);
break;
case COMPARE_IDENTICAL:
case COMPARE_NOT_IDENTICAL:
Token op = expression.getOperation();
Throwable cause = new SyntaxException("Operator " + op + " not supported", op.getStartLine(), op.getStartColumn(), op.getStartLine(), op.getStartColumn() + 3);
throw new GroovyRuntimeException(cause);
default:
throw new GroovyBugError("Operation: " + expression.getOperation() + " not supported");
}
}
use of org.codehaus.groovy.syntax.SyntaxException in project groovy-core by groovy.
the class InvocationWriter method makeMOPBasedConstructorCall.
private void makeMOPBasedConstructorCall(List<ConstructorNode> constructors, ConstructorCallExpression call, ClassNode callNode) {
MethodVisitor mv = controller.getMethodVisitor();
OperandStack operandStack = controller.getOperandStack();
call.getArguments().visit(controller.getAcg());
// keep Object[] on stack
mv.visitInsn(DUP);
// to select the constructor we need also the number of
// available constructors and the class we want to make
// the call on
BytecodeHelper.pushConstant(mv, -1);
controller.getAcg().visitClassExpression(new ClassExpression(callNode));
operandStack.remove(1);
// removes one Object[] leaves the int containing the
// call flags and the constructor number
selectConstructorAndTransformArguments.call(mv);
// load "this"
if (controller.isConstructor()) {
mv.visitVarInsn(ALOAD, 0);
} else {
mv.visitTypeInsn(NEW, BytecodeHelper.getClassInternalName(callNode));
}
mv.visitInsn(SWAP);
TreeMap<Integer, ConstructorNode> sortedConstructors = new TreeMap<Integer, ConstructorNode>();
for (ConstructorNode constructor : constructors) {
String typeDescriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, constructor.getParameters());
int hash = BytecodeHelper.hashCode(typeDescriptor);
ConstructorNode sameHashNode = sortedConstructors.put(hash, constructor);
if (sameHashNode != null) {
controller.getSourceUnit().addError(new SyntaxException("Unable to compile class " + controller.getClassNode().getName() + " due to hash collision in constructors", call.getLineNumber(), call.getColumnNumber()));
}
}
Label[] targets = new Label[constructors.size()];
int[] indices = new int[constructors.size()];
Iterator<Integer> hashIt = sortedConstructors.keySet().iterator();
Iterator<ConstructorNode> constructorIt = sortedConstructors.values().iterator();
for (int i = 0; i < targets.length; i++) {
targets[i] = new Label();
indices[i] = hashIt.next();
}
// create switch targets
Label defaultLabel = new Label();
Label afterSwitch = new Label();
mv.visitLookupSwitchInsn(defaultLabel, indices, targets);
for (int i = 0; i < targets.length; i++) {
mv.visitLabel(targets[i]);
// to extract the parameters.
if (controller.isConstructor()) {
// in this case we need one "this", so a SWAP will exchange
// "this" and Object[], a DUP_X1 will then copy the Object[]
// / to the last place in the stack:
// Object[],this -SWAP-> this,Object[]
// this,Object[] -DUP_X1-> Object[],this,Object[]
mv.visitInsn(SWAP);
mv.visitInsn(DUP_X1);
} else {
// in this case we need two "this" in between and the Object[]
// at the bottom of the stack as well as on top for our invokeSpecial
// So we do DUP_X1, DUP2_X1, POP
// Object[],this -DUP_X1-> this,Object[],this
// this,Object[],this -DUP2_X1-> Object[],this,this,Object[],this
// Object[],this,this,Object[],this -POP-> Object[],this,this,Object[]
mv.visitInsn(DUP_X1);
mv.visitInsn(DUP2_X1);
mv.visitInsn(POP);
}
ConstructorNode cn = constructorIt.next();
String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, cn.getParameters());
// unwrap the Object[] and make transformations if needed
// that means, to duplicate the Object[], make a cast with possible
// unboxing and then swap it with the Object[] for each parameter
// vargs need special attention and transformation though
Parameter[] parameters = cn.getParameters();
int lengthWithoutVargs = parameters.length;
if (parameters.length > 0 && parameters[parameters.length - 1].getType().isArray()) {
lengthWithoutVargs--;
}
for (int p = 0; p < lengthWithoutVargs; p++) {
loadAndCastElement(operandStack, mv, parameters, p);
}
if (parameters.length > lengthWithoutVargs) {
ClassNode type = parameters[lengthWithoutVargs].getType();
BytecodeHelper.pushConstant(mv, lengthWithoutVargs);
controller.getAcg().visitClassExpression(new ClassExpression(type));
operandStack.remove(1);
castToVargsArray.call(mv);
BytecodeHelper.doCast(mv, type);
} else {
// at the end we remove the Object[]
// the vargs case simply the last swap so no pop is needed
mv.visitInsn(POP);
}
// make the constructor call
mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false);
mv.visitJumpInsn(GOTO, afterSwitch);
}
mv.visitLabel(defaultLabel);
// this part should never be reached!
mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
mv.visitInsn(DUP);
mv.visitLdcInsn("This class has been compiled with a super class which is binary incompatible with the current super class found on classpath. You should recompile this class with the new version.");
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false);
mv.visitInsn(ATHROW);
mv.visitLabel(afterSwitch);
// result on the stack, which we can remove now if inside a constructor.
if (!controller.isConstructor()) {
// in case we are not in a constructor we have an additional
// object on the stack, the result of our constructor call
// which we want to keep, so we swap with the dummy object and
// do normal removal of it. In the end, the call result will be
// on the stack then
mv.visitInsn(SWAP);
// for call result
operandStack.push(callNode);
}
mv.visitInsn(POP);
}
use of org.codehaus.groovy.syntax.SyntaxException in project groovy-core by groovy.
the class NAryOperationRewriter method transformPostfixExpression.
private Expression transformPostfixExpression(final PostfixExpression exp) {
if (isInternalFieldAccess(exp.getExpression())) {
Token operation = exp.getOperation();
sourceUnit.addError(new SyntaxException("Postfix expressions on trait fields/properties are not supported in traits.", operation.getStartLine(), operation.getStartColumn()));
return exp;
} else {
return super.transform(exp);
}
}
use of org.codehaus.groovy.syntax.SyntaxException in project groovy-core by groovy.
the class TraitASTTransformation method createHelperClass.
private void createHelperClass(final ClassNode cNode) {
ClassNode helper = new InnerClassNode(cNode, Traits.helperClassName(cNode), ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE, ClassNode.EMPTY_ARRAY, null);
cNode.setModifiers(ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT);
checkInnerClasses(cNode);
MethodNode initializer = createInitMethod(false, cNode, helper);
MethodNode staticInitializer = createInitMethod(true, cNode, helper);
// apply the verifier to have the property nodes generated
generatePropertyMethods(cNode);
// prepare fields
List<FieldNode> fields = new ArrayList<FieldNode>();
Set<String> fieldNames = new HashSet<String>();
for (FieldNode field : cNode.getFields()) {
if (!"metaClass".equals(field.getName()) && (!field.isSynthetic() || field.getName().indexOf('$') < 0)) {
fields.add(field);
fieldNames.add(field.getName());
}
}
ClassNode fieldHelper = null;
if (!fields.isEmpty()) {
fieldHelper = new InnerClassNode(cNode, Traits.fieldHelperClassName(cNode), ACC_STATIC | ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT, ClassHelper.OBJECT_TYPE);
}
// add methods
List<MethodNode> methods = new ArrayList<MethodNode>(cNode.getMethods());
List<MethodNode> nonPublicAPIMethods = new LinkedList<MethodNode>();
for (final MethodNode methodNode : methods) {
boolean declared = methodNode.getDeclaringClass() == cNode;
if (declared) {
if (!methodNode.isSynthetic() && (methodNode.isProtected() || methodNode.getModifiers() == 0)) {
unit.addError(new SyntaxException("Cannot have protected/package private method in a trait (" + cNode.getName() + "#" + methodNode.getTypeDescriptor() + ")", methodNode.getLineNumber(), methodNode.getColumnNumber()));
return;
}
helper.addMethod(processMethod(cNode, methodNode, fieldHelper, fieldNames));
if (methodNode.isPrivate() || methodNode.isStatic()) {
nonPublicAPIMethods.add(methodNode);
}
}
}
// remove methods which should not appear in the trait interface
for (MethodNode privateMethod : nonPublicAPIMethods) {
cNode.removeMethod(privateMethod);
}
// add fields
for (FieldNode field : fields) {
processField(field, initializer, staticInitializer, fieldHelper, cNode, fieldNames);
}
// clear properties to avoid generation of methods
cNode.getProperties().clear();
// copy annotations
copyClassAnnotations(cNode, helper);
// reuse the full list of fields
fields = new ArrayList<FieldNode>(cNode.getFields());
for (FieldNode field : fields) {
cNode.removeField(field.getName());
}
// visit AST xforms
registerASTTranformations(helper);
unit.getAST().addClass(helper);
if (fieldHelper != null) {
unit.getAST().addClass(fieldHelper);
}
// resolve scope (for closures)
resolveScope(helper);
if (fieldHelper != null) {
resolveScope(fieldHelper);
}
}
Aggregations