protected Expression instantiate(Object oldInstance, Encoder out) { Class oldClass = (Class) oldInstance; // Due to the special handling of String instances in the Encoder // this Expression does not lead to further class resolutions. if (oldClass == String.class) return new Expression(oldClass, "", "getClass", null); // This Expression will lead to the class resolution of String.class. if (oldClass == Class.class) return new Expression(oldClass, String.class, "getClass", null); // This Expression will lead to the class resolution of Class.class. return new Expression(oldClass, Class.class, "forName", new Object[] { oldClass.getName() }); }
protected Expression instantiate(Object oldInstance, Encoder out) { Class type = oldInstance.getClass().getComponentType(); // oldInstance is expected to be an array, then // getClass().getComponentType() should lead // to its component type. assert (type != null); // Not handling primitive types in a special way here // causes that Class.forName("int") is built as an Expression // later which would cause an exception if executed. A special // handling to avoid the execution for primitive types can be // java.beans.Encoder.writeExpression() . return new Expression( oldInstance, Array.class, "newInstance", new Object[] { type, new Integer(Array.getLength(oldInstance)) }); }
@Override protected Expression instantiate( Object oldInstance, Encoder out ) { Class type = oldInstance.getClass(); if ( !Modifier.isPublic( type.getModifiers() ) ) throw new IllegalArgumentException( "Could not instantiate instance of non-public class: " + oldInstance ); for ( Field field : type.getFields() ) { int mod = field.getModifiers(); if ( Modifier.isPublic( mod ) && Modifier.isStatic( mod ) && Modifier.isFinal( mod ) && ( type == field.getDeclaringClass() ) ) { try { if ( oldInstance == field.get( null ) ) return new Expression( oldInstance, field, "get", new Object[]{null} ); } catch ( IllegalAccessException exception ) { throw new IllegalArgumentException( "Could not get value of the field: " + field, exception ); } } } throw new IllegalArgumentException( "Could not instantiate value: " + oldInstance ); }
@Test public void testDiamond() throws Exception { if (SourceVersion.latestSupported().ordinal() >= 7) { compile("import java.util.List; import java.util.LinkedList; public class A{ List<Integer> bar = new LinkedList<>(); }"); SymbolTable symTable = getSymbolTable(); symTable.pushScope(); SymbolType st = new SymbolType(getClassLoader().loadClass("A")); symTable.pushSymbol("a", ReferenceType.VARIABLE, st, null); FieldAccessExpr expr = (FieldAccessExpr) ASTManager.parse(Expression.class, "a.bar"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expressionAnalyzer.visit(expr, ctx); SymbolType type = (SymbolType) expr.getSymbolData(); Assert.assertNotNull(type); Assert.assertEquals("java.util.List", type.getName()); Assert.assertNotNull(type.getParameterizedTypes()); Assert.assertEquals("java.lang.Integer", type.getParameterizedTypes().get(0).getName()); } }
@Test public void testTargetInference() throws Exception { compile("import java.util.Collections; " + "import java.util.List; " + "public class A { public static void processStringList(List<String> stringList) {}}"); SymbolType st = new SymbolType(getClassLoader().loadClass("A")); SymbolTable symTable = getSymbolTable(); symTable.pushScope(); symTable.pushSymbol("A", ReferenceType.TYPE, st, null); MethodCallExpr expr = (MethodCallExpr) ASTManager.parse(Expression.class, "A.processStringList(Collections.emptyList());"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expressionAnalyzer.visit(expr, ctx); SymbolType type = (SymbolType) expr.getSymbolData(); Assert.assertNotNull(type); Assert.assertEquals("void", type.getName()); }
@Test public void testLambdaExpressionsWithExplicitArgs() throws Exception { if (SourceVersion.latestSupported().ordinal() >= 8) { String BCode = "public interface B { public int execute(int c); } "; compile("public class A{ public void run(B b){} " + BCode + "}"); SymbolType st = new SymbolType(getClassLoader().loadClass("A")); SymbolTable symTable = getSymbolTable(); symTable.pushScope(); symTable.pushSymbol("a", ReferenceType.TYPE, st, null); MethodCallExpr expr = (MethodCallExpr) ASTManager.parse(Expression.class, "a.run((int d)->d+1)"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expressionAnalyzer.visit(expr, ctx); SymbolType type = (SymbolType) expr.getSymbolData(); Assert.assertNotNull(type); Assert.assertEquals("A$B", type.getMethod().getParameterTypes()[0].getName()); } }
@Test public void testMethodReferencesToConstructors() throws Exception { if (SourceVersion.latestSupported().ordinal() >= 8) { compile("import java.util.HashSet; public class A{ public static void foo(B b) {} public interface B{ public Object get();}}"); SymbolTable symTable = getSymbolTable(); symTable.pushSymbol("this", ReferenceType.TYPE, new SymbolType(getClassLoader().loadClass("A")), null); MethodCallExpr expr = (MethodCallExpr) ASTManager.parse(Expression.class, "A.foo(HashSet::new)"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expressionAnalyzer.visit(expr, ctx); SymbolType type = (SymbolType) expr.getSymbolData(); Assert.assertNotNull(type); Assert.assertEquals("foo", type.getMethod().getName()); MethodReferenceExpr arg1 = (MethodReferenceExpr) expr.getArgs().get(0); SymbolType methodType = (SymbolType) arg1.getReferencedMethodSymbolData(); Assert.assertNotNull(methodType); Assert.assertEquals("get", methodType.getMethod().getName()); } }
@Test public void testTargetInferenceShouldFail() throws Exception { compile("import java.util.Collections; " + "import java.util.List; " + "public class A { public static <T> void processStringList(T[] args) {}}"); SymbolType st = new SymbolType(getClassLoader().loadClass("A")); SymbolTable symTable = getSymbolTable(); symTable.pushScope(); symTable.pushSymbol("A", ReferenceType.TYPE, st, null); try { MethodCallExpr expr = (MethodCallExpr) ASTManager.parse(Expression.class, "A.processStringList(Collections.emptyList());"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expressionAnalyzer.visit(expr, ctx); fail("should not be reached: type=" + expr.getSymbolData().getMethod()); } catch (NoSuchExpressionTypeException e) { Assert.assertTrue(e.getMessage(), e.getMessage() .contains("Ops! The method call A.processStringList(Collections.emptyList()) is not resolved")); } }
/** * The test checks the correct static method is initialized */ public void testStatic() throws Exception { SampleBean theBean = new SampleBean(); Expression expr = new Expression(SampleBean.class, "create", new Object[] { "hello", theBean }); Object result = expr.getValue(); if (result != null && result instanceof SampleBean) { SampleBean bean = (SampleBean) result; assertEquals("hello", bean.getText()); assertEquals(theBean, bean.getObject()); } else { fail("Cannot instantiate an instance of Bean class by " + "static method."); } }
@Test public void testMethodReferencesToAnArrayItem() throws Exception { if (SourceVersion.latestSupported().ordinal() >= 8) { compile("import java.util.Arrays; public class A{}"); SymbolType st = new SymbolType(String.class); st.setArrayCount(1); SymbolTable symTable = getSymbolTable(); symTable.pushScope(); symTable.pushSymbol("stringArray", ReferenceType.TYPE, st, null); symTable.pushSymbol("this", ReferenceType.TYPE, new SymbolType(getClassLoader().loadClass("A")), null); MethodCallExpr expr = (MethodCallExpr) ASTManager.parse(Expression.class, "Arrays.sort(stringArray, String::compareToIgnoreCase)"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expressionAnalyzer.visit(expr, ctx); SymbolType type = (SymbolType) expr.getSymbolData(); Assert.assertNotNull(type); Assert.assertEquals("sort", type.getMethod().getName()); MethodReferenceExpr arg1 = (MethodReferenceExpr) expr.getArgs().get(1); SymbolType methodType = (SymbolType) arg1.getReferencedMethodSymbolData(); Assert.assertNotNull(methodType); Assert.assertEquals("compare", methodType.getMethod().getName()); } }
@Test public void testGenericMethodsExplicitTypeInvocation() throws Exception { compile("import java.util.ArrayList; import java.io.Serializable;" + " public class A { public static <T> T pick(T a1, T a2) { return a2; }}"); SymbolTable symTable = getSymbolTable(); ASTSymbolTypeResolver.getInstance().setSymbolTable(symTable); symTable.pushScope(); SymbolType st = new SymbolType(getClassLoader().loadClass("A")); symTable.pushSymbol("A", ReferenceType.TYPE, st, null); MethodCallExpr expr = (MethodCallExpr) ASTManager.parse(Expression.class, "A.<Serializable>pick(\"d\", new ArrayList<String>())"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expressionAnalyzer.visit(expr, ctx); SymbolType type = (SymbolType) expr.getSymbolData(); Assert.assertNotNull(type); Assert.assertEquals("java.io.Serializable", type.getName()); }
public void testTargetInference2() throws Exception { compile("import java.util.Collections; " + "import java.util.List; " + "public class A { public static void processAList(List<A> stringList) {}}"); SymbolType st = new SymbolType(getClassLoader().loadClass("A")); SymbolTable symTable = getSymbolTable(); symTable.pushScope(); symTable.pushSymbol("A", ReferenceType.TYPE, st, null); MethodCallExpr expr = (MethodCallExpr) ASTManager.parse(Expression.class, "A.processAList(Collections.emptyList());"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expressionAnalyzer.visit(expr, ctx); SymbolType type = (SymbolType) expr.getSymbolData(); Assert.assertNotNull(type); Assert.assertEquals("void", type.getName()); }
@Test public void testReferencesToInnerClasses() throws Exception { compile(true, "public class OuterClass { public class InnerClass { } }"); SymbolTable symTable = getSymbolTable(); ASTSymbolTypeResolver.getInstance().setSymbolTable(symTable); symTable.pushScope(); SymbolType st = new SymbolType(getClassLoader().loadClass("OuterClass")); symTable.pushSymbol("outerObject", ReferenceType.VARIABLE, st, null); org.walkmod.javalang.ast.expr.Expression expr = (org.walkmod.javalang.ast.expr.Expression) ASTManager .parse(Expression.class, "outerObject.new InnerClass()"); HashMap<String, Object> ctx = new HashMap<String, Object>(); expr.accept(expressionAnalyzer, ctx); SymbolType type = (SymbolType) expr.getSymbolData(); Assert.assertNotNull(type); Assert.assertEquals("OuterClass$InnerClass", type.getName()); }
@Override protected Expression instantiate(Object oldInstance, Encoder out) { byte[] e = (byte[]) oldInstance; return new Expression(e, ByteArrayPersistenceDelegate.class, "decode", new Object[] { ByteArrayPersistenceDelegate.encode(e) }); }
/** * Creates the value of this element. * * @param type the base class * @param args the array of arguments * @return the value of this element * @throws Exception if calculation is failed */ @Override protected final ValueObject getValueObject(Class<?> type, Object[] args) throws Exception { if (this.field != null) { return ValueObjectImpl.create(FieldElementHandler.getFieldValue(getContextBean(), this.field)); } if (this.idref != null) { return ValueObjectImpl.create(getVariable(this.idref)); } Object bean = getContextBean(); String name; if (this.index != null) { name = (args.length == 2) ? PropertyElementHandler.SETTER : PropertyElementHandler.GETTER; } else if (this.property != null) { name = (args.length == 1) ? PropertyElementHandler.SETTER : PropertyElementHandler.GETTER; if (0 < this.property.length()) { name += this.property.substring(0, 1).toUpperCase(ENGLISH) + this.property.substring(1); } } else { name = (this.method != null) && (0 < this.method.length()) ? this.method : "new"; // NON-NLS: the constructor marker } Expression expression = new Expression(bean, name, args); return ValueObjectImpl.create(expression.getValue()); }
public static void main(String[] args) throws Exception { Object value = new Object(); Expression expression = new Expression(value, Object.class, "new", null); if (!value.equals(expression.getValue())) throw new Error("the value is updated unexpectedly"); expression.execute(); if (value.equals(expression.getValue())) throw new Error("the value is not updated as expected"); }
@Override public void writeExpression(Expression expression) { if (this.expression == null) { this.expression = expression; } super.writeExpression(expression); }
protected void initialize(XMLEncoder encoder) { encoder.setPersistenceDelegate(Container.class, new PersistenceDelegate() { protected Expression instantiate(Object oldInstance, Encoder out) { Container container = (Container) oldInstance; Component component = container.getComponent(); return new Expression(container, component, "create", new Object[] {component}); } }); }
protected void initialize(XMLEncoder encoder) { encoder.setPersistenceDelegate( OuterClass.InnerClass.class, new DefaultPersistenceDelegate() { protected Expression instantiate(Object oldInstance, Encoder out) { OuterClass.InnerClass inner = (OuterClass.InnerClass) oldInstance; OuterClass outer = inner.getOuter(); return new Expression(inner, outer, "getInner", new Object[0]); } } ); }
protected void initialize(XMLEncoder encoder) { encoder.setPersistenceDelegate(C.class, new DefaultPersistenceDelegate() { protected Expression instantiate(Object oldInstance, Encoder out) { C c = (C) oldInstance; return new Expression(c, c.getX(), "createC", new Object[] {}); } }); }
@SuppressWarnings("unchecked") public static <E,R> R getMethodValue(E obj, Method method, Object... args) { R value = null; try { method.setAccessible(true); value = (R) method.invoke(obj, args); } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) { // e.printStackTrace(); try { if (obj != null) { Expression expr = new Expression(obj, method.getName(), args); expr.execute(); value = (R) expr.getValue(); } if (value == null) { value = (R) method.getDefaultValue(); } } catch (Exception e1) { // e1.printStackTrace(); } } return value; }