use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class AsmClassGenerator method visitAttributeOrProperty.
private void visitAttributeOrProperty(PropertyExpression expression, MethodCallerMultiAdapter adapter) {
MethodVisitor mv = controller.getMethodVisitor();
Expression objectExpression = expression.getObjectExpression();
ClassNode classNode = controller.getClassNode();
if (isThisOrSuper(objectExpression)) {
// let's use the field expression if it's available
String name = expression.getPropertyAsString();
if (name != null) {
FieldNode field = null;
boolean privateSuperField = false;
if (isSuperExpression(objectExpression)) {
field = classNode.getSuperClass().getDeclaredField(name);
if (field != null && ((field.getModifiers() & ACC_PRIVATE) != 0)) {
privateSuperField = true;
}
} else {
if (controller.isNotExplicitThisInClosure(expression.isImplicitThis())) {
field = classNode.getDeclaredField(name);
if (field == null && classNode instanceof InnerClassNode) {
ClassNode outer = classNode.getOuterClass();
FieldNode outerClassField;
while (outer != null) {
outerClassField = outer.getDeclaredField(name);
if (outerClassField != null && outerClassField.isStatic() && outerClassField.isFinal()) {
if (outer != classNode.getOuterClass() && Modifier.isPrivate(outerClassField.getModifiers())) {
throw new GroovyBugError("Trying to access private constant field [" + outerClassField.getDeclaringClass() + "#" + outerClassField.getName() + "] from inner class");
}
PropertyExpression pexp = new PropertyExpression(new ClassExpression(outer), expression.getProperty());
pexp.visit(controller.getAcg());
return;
}
outer = outer.getSuperClass();
}
}
if (field == null && expression instanceof AttributeExpression && isThisExpression(objectExpression) && controller.isStaticContext()) {
// GROOVY-6183
ClassNode current = classNode.getSuperClass();
while (field == null && current != null) {
field = current.getDeclaredField(name);
current = current.getSuperClass();
}
if (field != null && (field.isProtected() || field.isPublic())) {
visitFieldExpression(new FieldExpression(field));
return;
}
}
}
}
if (field != null && !privateSuperField) {
//GROOVY-4497: don't visit super field if it is private
visitFieldExpression(new FieldExpression(field));
return;
}
}
if (isSuperExpression(objectExpression)) {
String prefix;
if (controller.getCompileStack().isLHS()) {
throw new GroovyBugError("Unexpected super property set for:" + expression.getText());
} else {
prefix = "get";
}
String propName = prefix + MetaClassHelper.capitalize(name);
visitMethodCallExpression(new MethodCallExpression(objectExpression, propName, MethodCallExpression.NO_ARGUMENTS));
return;
}
}
final String propName = expression.getPropertyAsString();
//TODO: add support for super here too
if (expression.getObjectExpression() instanceof ClassExpression && propName != null && propName.equals("this")) {
// we have something like A.B.this, and need to make it
// into this.this$0.this$0, where this.this$0 returns
// A.B and this.this$0.this$0 return A.
ClassNode type = objectExpression.getType();
ClassNode iterType = classNode;
if (controller.getCompileStack().isInSpecialConstructorCall() && classNode instanceof InnerClassNode) {
boolean staticInnerClass = classNode.isStaticClass();
// Outer.this in a special constructor call
if (classNode.getOuterClass().equals(type)) {
ConstructorNode ctor = controller.getConstructorNode();
Expression receiver = !staticInnerClass ? new VariableExpression(ctor.getParameters()[0]) : new ClassExpression(type);
receiver.setSourcePosition(expression);
receiver.visit(this);
return;
}
}
mv.visitVarInsn(ALOAD, 0);
while (!iterType.equals(type)) {
String ownerName = BytecodeHelper.getClassInternalName(iterType);
if (iterType.getOuterClass() == null)
break;
FieldNode thisField = iterType.getField("this$0");
if (thisField == null)
break;
ClassNode thisFieldType = thisField.getType();
iterType = iterType.getOuterClass();
if (ClassHelper.CLOSURE_TYPE.equals(thisFieldType)) {
mv.visitFieldInsn(GETFIELD, ownerName, "this$0", BytecodeHelper.getTypeDescription(ClassHelper.CLOSURE_TYPE));
mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(ClassHelper.CLOSURE_TYPE), "getThisObject", "()Ljava/lang/Object;", false);
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(iterType));
} else {
String typeName = BytecodeHelper.getTypeDescription(iterType);
mv.visitFieldInsn(GETFIELD, ownerName, "this$0", typeName);
}
}
controller.getOperandStack().push(type);
return;
}
if (adapter == getProperty && !expression.isSpreadSafe() && propName != null) {
controller.getCallSiteWriter().makeGetPropertySite(objectExpression, propName, expression.isSafe(), expression.isImplicitThis());
} else if (adapter == getGroovyObjectProperty && !expression.isSpreadSafe() && propName != null) {
controller.getCallSiteWriter().makeGroovyObjectGetPropertySite(objectExpression, propName, expression.isSafe(), expression.isImplicitThis());
} else {
// todo: for improved modularity and extensibility, this should be moved into a writer
if (controller.getCompileStack().isLHS())
controller.getOperandStack().box();
controller.getInvocationWriter().makeCall(expression, // receiver
objectExpression, // messageName
new CastExpression(ClassHelper.STRING_TYPE, expression.getProperty()), MethodCallExpression.NO_ARGUMENTS, adapter, expression.isSafe(), expression.isSpreadSafe(), expression.isImplicitThis());
}
}
use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class CompileStack method init.
/**
* initializes this class for a MethodNode. This method will
* automatically define variables for the method parameters
* and will create references if needed. The created variables
* can be accessed by calling getVariable().
*
*/
public void init(VariableScope el, Parameter[] parameters) {
if (!clear)
throw new GroovyBugError("CompileStack#init called without calling clear before");
clear = false;
pushVariableScope(el);
defineMethodVariables(parameters, el.isInStaticContext());
this.className = BytecodeHelper.getTypeDescription(controller.getClassNode());
}
use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class OperandStack method castToBool.
/**
* ensure last marked parameter on the stack is a primitive boolean
* if mark==stack size, we assume an empty expression or statement.
* was used and we will use the value given in emptyDefault as boolean
* if mark==stack.size()-1 the top element will be cast to boolean using
* Groovy truth.
* In other cases we throw a GroovyBugError
*/
public void castToBool(int mark, boolean emptyDefault) {
int size = stack.size();
MethodVisitor mv = controller.getMethodVisitor();
if (mark == size) {
// no element, so use emptyDefault
if (emptyDefault) {
mv.visitIntInsn(BIPUSH, 1);
} else {
mv.visitIntInsn(BIPUSH, 0);
}
stack.add(null);
} else if (mark == stack.size() - 1) {
ClassNode last = stack.get(size - 1);
// nothing to do in that case
if (last == ClassHelper.boolean_TYPE)
return;
// not a primitive type, so call booleanUnbox
if (!ClassHelper.isPrimitiveType(last)) {
controller.getInvocationWriter().castNonPrimitiveToBool(last);
} else {
primitive2b(mv, last);
}
} else {
throw new GroovyBugError("operand stack contains " + stack.size() + " elements, but we expected only " + mark);
}
stack.set(mark, ClassHelper.boolean_TYPE);
}
use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class SourceUnit method parse.
//---------------------------------------------------------------------------
// PROCESSING
/**
* Parses the source to a CST. You can retrieve it with getCST().
*/
public void parse() throws CompilationFailedException {
if (this.phase > Phases.PARSING) {
throw new GroovyBugError("parsing is already complete");
}
if (this.phase == Phases.INITIALIZATION) {
nextPhase();
}
//
// Create a reader on the source and run the parser.
Reader reader = null;
try {
reader = source.getReader();
// let's recreate the parser each time as it tends to keep around state
parserPlugin = getConfiguration().getPluginFactory().createParserPlugin();
cst = parserPlugin.parseCST(this, reader);
reader.close();
} catch (IOException e) {
getErrorCollector().addFatalError(new SimpleMessage(e.getMessage(), this));
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// Ignore
}
}
}
}
use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class Traits method findHelpers.
static TraitHelpersTuple findHelpers(final ClassNode trait) {
ClassNode helperClassNode = null;
ClassNode fieldHelperClassNode = null;
Iterator<InnerClassNode> innerClasses = trait.redirect().getInnerClasses();
if (innerClasses != null && innerClasses.hasNext()) {
// trait defined in same source unit
while (innerClasses.hasNext()) {
ClassNode icn = innerClasses.next();
if (icn.getName().endsWith(Traits.FIELD_HELPER)) {
fieldHelperClassNode = icn;
} else if (icn.getName().endsWith(Traits.TRAIT_HELPER)) {
helperClassNode = icn;
}
}
} else {
// precompiled trait
try {
final ClassLoader classLoader = trait.getTypeClass().getClassLoader();
String helperClassName = Traits.helperClassName(trait);
helperClassNode = ClassHelper.make(classLoader.loadClass(helperClassName));
try {
fieldHelperClassNode = ClassHelper.make(classLoader.loadClass(Traits.fieldHelperClassName(trait)));
} catch (ClassNotFoundException e) {
// not a problem, the field helper may be absent
}
} catch (ClassNotFoundException e) {
throw new GroovyBugError("Couldn't find trait helper classes on compile classpath!", e);
}
}
return new TraitHelpersTuple(helperClassNode, fieldHelperClassNode);
}
Aggregations