Skip to content

Commit

Permalink
Merge pull request #416 from GerardPaligot/fix_405
Browse files Browse the repository at this point in the history
  • Loading branch information
monperrus committed Nov 20, 2015
2 parents de4b0d2 + 8a0927b commit d24ccbd
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 15 deletions.
34 changes: 25 additions & 9 deletions src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,14 @@ void enter(CtElement e, ASTNode node) {
((CtStatement) current).setLabel(context.label.pop());
}

if (e instanceof CtTypedElement && node instanceof Expression) {
if (((CtTypedElement<?>) e).getType() == null && !(e instanceof CtInvocation)) {
((CtTypedElement<Object>) e).setType(references.getTypeReference(((Expression) node).resolvedType));
try {
if (e instanceof CtTypedElement && node instanceof Expression) {
if (((CtTypedElement<?>) e).getType() == null) {
((CtTypedElement<Object>) e).setType(references.getTypeReference(((Expression) node).resolvedType));
}
}
} catch (UnsupportedOperationException ignore) {
// For some element, we throw an UnsupportedOperationException when we call setType().
}

}
Expand Down Expand Up @@ -1654,6 +1658,22 @@ public boolean visit(AllocationExpression allocationExpression, BlockScope scope
}

private <T extends CtConstructorCall<Object>> T buildCommonPartForCtNewClassAndCtConstructorCall(AllocationExpression allocationExpression, BlockScope scope, T constructorCall) {
if (allocationExpression.binding != null) {
constructorCall.setExecutable(references.getExecutableReference(allocationExpression.binding));
} else {
final CtExecutableReference<Object> ref = factory.Core().createExecutableReference();
ref.setSimpleName(CtExecutableReference.CONSTRUCTOR_NAME);
ref.setType(references.getTypeReference(null, allocationExpression.type));
ref.setDeclaringType(references.getTypeReference(null, allocationExpression.type));

final List<CtTypeReference<?>> parameters = new ArrayList<CtTypeReference<?>>(allocationExpression.argumentTypes.length);
for (TypeBinding b : allocationExpression.argumentTypes) {
parameters.add(references.getTypeReference(b));
}
ref.setParameters(parameters);
constructorCall.setExecutable(ref);
}

if (allocationExpression.type != null) {
final TypeReference[][] typeArguments = allocationExpression.type.getTypeArguments();
// If typeArguments are null or empty, we have an element with a generic type.
Expand All @@ -1668,14 +1688,10 @@ private <T extends CtConstructorCall<Object>> T buildCommonPartForCtNewClassAndC
}
}
}
constructorCall.setType(references.getTypeReference(allocationExpression.type.resolvedType));
constructorCall.getExecutable().setType(references.getTypeReference(allocationExpression.type.resolvedType));
context.isGenericTypeExplicit = true;
} else if (allocationExpression.expectedType() != null) {
constructorCall.setType(references.getTypeReference(allocationExpression.expectedType()));
}
constructorCall.setExecutable(references.getExecutableReference(allocationExpression.binding));
if (constructorCall.getExecutable() != null) {
constructorCall.getExecutable().setType((CtTypeReference<Object>) constructorCall.getExecutable().getDeclaringType());
constructorCall.getExecutable().setType(references.getTypeReference(allocationExpression.expectedType()));
}

if (allocationExpression.genericTypeArguments() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtStatementList;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtTypedElement;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtGenericElementReference;
import spoon.reflect.reference.CtTypeReference;
Expand Down Expand Up @@ -152,4 +153,14 @@ public boolean removeActualTypeArgument(CtTypeReference<?> actualTypeArgument) {
return actualTypeArguments != CtElementImpl.<CtTypeReference<?>>emptyList()
&& actualTypeArguments.remove(actualTypeArgument);
}

@Override
public CtTypeReference<T> getType() {
return getExecutable() == null ? null : getExecutable().getType();
}

@Override
public <C extends CtTypedElement> C setType(CtTypeReference<T> type) {
throw new UnsupportedOperationException("Uses getExecutable().setType(CtTypeReference<T>)");
}
}
35 changes: 29 additions & 6 deletions src/test/java/spoon/test/executable/ExecutableRefTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.junit.Assert;
import org.junit.Test;
import spoon.Launcher;
import spoon.reflect.code.CtAbstractInvocation;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtConstructorCall;
Expand All @@ -12,12 +13,16 @@
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.test.TestUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class ExecutableRefTest {

@Test
Expand All @@ -31,7 +36,7 @@ public void methodTest() throws Exception {
Method method = executableReference.getActualMethod();
Assert.assertNotNull(method);

Assert.assertEquals("Hello World",
assertEquals("Hello World",
method.invoke(null, ((CtLiteral<?>) ctAbstractInvocation.getArguments().get(0)).getValue()));
}

Expand All @@ -46,7 +51,7 @@ public void constructorTest() throws Exception {
Constructor<?> constructor = executableReference.getActualConstructor();
Assert.assertNotNull(constructor);

Assert.assertEquals("Hello World",
assertEquals("Hello World",
constructor.newInstance(((CtLiteral<?>) ctAbstractInvocation.getArguments().get(0)).getValue()));
}

Expand All @@ -58,8 +63,26 @@ public void testGetActualClassTest() throws Exception {
CtExecutableReference<?> ref = method.getReference();

Method m = ref.getActualMethod();
Assert.assertEquals("myMethod", m.getName());
Assert.assertEquals(0, m.getExceptionTypes().length);
assertEquals("myMethod", m.getName());
assertEquals(0, m.getExceptionTypes().length);
}

@Test
public void testSameTypeInConstructorCallBetweenItsObjectAndItsExecutable() {
final Launcher launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
launcher.addInputResource("./src/test/resources/executable/CmiContext_1.2.java");
launcher.setSourceOutputDirectory("./target/executable");
launcher.run();

final CtClass<Object> aClass = launcher.getFactory().Class().get("org.objectweb.carol.jndi.spi.CmiContext");
final List<CtConstructorCall> ctConstructorCalls = aClass.getElements(new TypeFilter<>(CtConstructorCall.class));

for (CtConstructorCall constructorCall : ctConstructorCalls) {
assertNotNull(constructorCall.getExecutable());
}

TestUtils.canBeBuilt("./target/executable", 8, true);
}

private CtAbstractInvocation<?> getInvocationFromMethod(String methodName) throws Exception {
Expand All @@ -69,14 +92,14 @@ private CtAbstractInvocation<?> getInvocationFromMethod(String methodName) throw
Assert.assertNotNull(clazz);

List<CtMethod<?>> methods = clazz.getMethodsByName(methodName);
Assert.assertEquals(1, methods.size());
assertEquals(1, methods.size());

CtMethod<?> ctMethod = methods.get(0);
CtBlock<?> ctBody = (CtBlock<?>) ctMethod.getBody();
Assert.assertNotNull(ctBody);

List<CtStatement> ctStatements = ctBody.getStatements();
Assert.assertEquals(1, ctStatements.size());
assertEquals(1, ctStatements.size());

CtStatement ctStatement = ctStatements.get(0);
Assert.assertTrue(ctStatement instanceof CtAbstractInvocation<?>);
Expand Down
118 changes: 118 additions & 0 deletions src/test/resources/executable/CmiContext_1.2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/**
* Copyright (C) 2002-2006 - INRIA (www.inria.fr)
*
* CAROL: Common Architecture for RMI ObjectWeb Layer
*
* This library is developed inside the ObjectWeb Consortium,
* http://www.objectweb.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id: CmiContext.java,v 1.2 2006-01-26 16:28:55 pelletib Exp $
* --------------------------------------------------------------------------
*/
package org.objectweb.carol.jndi.spi;

import java.io.Serializable;
import java.rmi.Remote;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.rmi.CORBA.PortableRemoteObjectDelegate;

import org.objectweb.carol.jndi.wrapping.JNDIResourceWrapper;
import org.objectweb.carol.jndi.wrapping.UnicastJNDIReferenceWrapper;
import org.objectweb.carol.rmi.exception.NamingExceptionHelper;
import org.objectweb.carol.util.configuration.ConfigurationRepository;

/**
* @author Florent Benoit
* @author Benoit Pelletier
*/
public class CmiContext extends AbsContext implements Context {

/**
* Constructs an CMI Wrapper context
* @param cmiContext the inital CMI context
*/
public CmiContext(Context cmiContext) {
super(cmiContext);
}


/**
* If this object is a reference wrapper return the reference If this object
* is a resource wrapper return the resource
* @param o the object to resolve
* @param name name of the object to unwrap
* @return the unwrapped object
* @throws NamingException if the object cannot be unwraped
*/
protected Object unwrapObject(Object o, Name name) throws NamingException {
return super.defaultUnwrapObject(o, name);
}

/**
* Wrap an Object : If the object is a reference wrap it into a Reference
* Wrapper Object here the good way is to contact the carol configuration to
* get the portable remote object
* @param o the object to encode
* @param name of the object
* @param replace if the object need to be replaced
* @return a <code>Remote JNDIRemoteReference Object</code> if o is a
* resource o if else
* @throws NamingException if object cannot be wrapped
*/
protected Object wrapObject(Object o, Name name, boolean replace) throws NamingException {
try {
// Add wrapper for the two first cases. Then it will use PortableRemoteObject instead of UnicastRemoteObject
// and when fixing JRMP exported objects port, it use JRMPProdelegate which is OK.
if ((!(o instanceof Remote)) && (o instanceof Referenceable)) {
return new UnicastJNDIReferenceWrapper(((Referenceable) o).getReference(), getObjectPort());
} else if ((!(o instanceof Remote)) && (o instanceof Reference)) {
return new UnicastJNDIReferenceWrapper((Reference) o, getObjectPort());
} else if ((!(o instanceof Remote)) && (!(o instanceof Referenceable)) && (!(o instanceof Reference))
&& (o instanceof Serializable)) {
// Only Serializable (not implementing Remote or Referenceable or
// Reference)
JNDIResourceWrapper irw = new JNDIResourceWrapper((Serializable) o);
PortableRemoteObjectDelegate proDelegate = ConfigurationRepository.getCurrentConfiguration().getProtocol().getPortableRemoteObject();
proDelegate.exportObject(irw);

Remote oldObj = (Remote) addToExported(name, irw);
if (oldObj != null) {
if (replace) {
proDelegate.unexportObject(oldObj);
} else {
proDelegate.unexportObject(irw);
addToExported(name, oldObj);
throw new NamingException("Object '" + o + "' with name '" + name + "' is already bind");
}
}
return irw;
} else {
return o;
}
} catch (Exception e) {
throw NamingExceptionHelper.create("Cannot wrap object '" + o + "' with name '" + name + "' : "
+ e.getMessage(), e);
}
}
}

0 comments on commit d24ccbd

Please sign in to comment.