/******************************************************************************* * Copyright (c) 2005, 2007 committers of openArchitectureWare and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * committers of openArchitectureWare - initial API and implementation *******************************************************************************/ package org.eclipse.xtend; import java.io.StringReader; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import junit.framework.TestCase; import org.eclipse.internal.xtend.xtend.ast.ExpressionExtensionStatement; import org.eclipse.internal.xtend.xtend.ast.Extension; import org.eclipse.internal.xtend.xtend.ast.ExtensionFile; import org.eclipse.internal.xtend.xtend.parser.ParseFacade; import org.eclipse.xtend.expression.AnalysationIssue; import org.eclipse.xtend.expression.ExecutionContextImpl; import org.eclipse.xtend.type.impl.java.JavaMetaModel; import org.eclipse.xtend.type.impl.java.beans.JavaBeansStrategy; import org.eclipse.xtend.typesystem.Type; import org.eclipse.xtend.typesystem.javabeansimpl.test.TypeA; import org.eclipse.xtend.typesystem.javabeansimpl.test.TypeB; import org.eclipse.xtend.typesystem.javabeansimpl.test.TypeC; public class ExtensionAnalyzationTest extends TestCase { private Set<AnalysationIssue> issues; private ExecutionContextImpl ec; @Override protected void setUp() throws Exception { ec = new ExecutionContextImpl(); ec.registerMetaModel(new JavaMetaModel("asdf", new JavaBeansStrategy())); issues = new HashSet<AnalysationIssue>(); } private ExtensionFile parse(final String expression) { return ParseFacade.file(new StringReader(expression), "nofile"); } private void dumpIssues() { for (final Iterator<AnalysationIssue> iter = issues.iterator(); iter.hasNext();) { final AnalysationIssue element = iter.next(); System.out.println(element.getType().toString() + " - " + element.getMessage()); } } public final void testWithEverything() { final ExtensionFile file = parse("String toUpperCase(String str) : JAVA org.eclipse.xtend.Helper.toUpperCase(java.lang.String) ; \n" + "\n" + "String privateHelper(String str) :JAVA org.eclipse.xtend.Helper.privateHelper(java.lang.String) ; \n" + "\n" + "String nonStaticHelper(String str) :JAVA org.eclipse.xtend.Helper.nonStaticHelper(java.lang.String) ; \n" + "\n" + "/* \n" + " * Meine Funktion \n" + " */ \n" + "myExtension(Object val) : {val}; \n"); file.analyze(ec, issues); dumpIssues(); assertEquals(1, issues.size()); final ExpressionExtensionStatement ext = (ExpressionExtensionStatement) file.getExtensions().get(3); assertEquals(ec.getListType(ec.getBooleanType()), ext.getReturnType(new Type[] { ec.getBooleanType() }, ec, new HashSet<AnalysationIssue>())); assertEquals(ec.getListType(ec.getStringType()), ext.getReturnType(new Type[] { ec.getStringType() }, ec, new HashSet<AnalysationIssue>())); assertEquals(ec.getListType(ec.getObjectType()), ext.getReturnType(new Type[] { ec.getObjectType() }, ec, new HashSet<AnalysationIssue>())); } public final void testRecursionWithoutType() { final ExtensionFile file = parse("recExtension(Integer i) : i==0 ? {i} : recExtension(i-1).add(i) ; \n"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); final ExpressionExtensionStatement ext = (ExpressionExtensionStatement) file.getExtensions().get(0); final Type result = ext.getReturnType(new Type[] { ec.getIntegerType() }, ec, new HashSet<AnalysationIssue>()); assertNull(result); } public final void testRecursionWithType() { final ExtensionFile file = parse("List[Integer] recExtension(Integer i) : i==0 ? {i} : recExtension(i-1).add(i) ; \n"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); final ExpressionExtensionStatement ext = (ExpressionExtensionStatement) file.getExtensions().get(0); final Type result = ext.getReturnType(new Type[] { ec.getIntegerType() }, ec, new HashSet<AnalysationIssue>()); assertEquals(0, issues.size()); assertEquals(ec.getListType(ec.getIntegerType()), result); } public final void testMemberPosition() { final ExtensionFile file = parse("ext1(String txt) : 'test'+txt ;" + "ext2(String txt) : txt.ext1() ;"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); final Extension ext = ec.getExtensionForTypes("ext2", new Type[] { ec.getStringType() }); final Type evalResult = ext.getReturnType(new Type[] { ec.getStringType() }, ec, new HashSet<AnalysationIssue>()); assertEquals(ec.getStringType(), evalResult); } public final void testDuplicateParameterNames1() { final ExtensionFile file = parse("ext1(String txt, String txt) : 'test'+txt ;"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(1, issues.size()); } public final void testDuplicateParameterNames2() { final ExtensionFile file = parse("ext1(String txt, String txt2) : 'test'+txt ;"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(0, issues.size()); } public final void testThisParameterName() { final ExtensionFile file = parse("ext1(String this, String txt2) : 'test'+length ;"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(0, issues.size()); } public final void testCreateExtension() { final ExtensionFile file = parse("create List l test(String s) : l.add(s) ;"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(0, issues.size()); final Extension ext = file.getExtensions().get(0); assertEquals("List", ext.getReturnType(null, ec, null).getName()); } public final void testCreateExtension1() { final ExtensionFile file = parse("create List test(String s) : add(s) ;"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(0, issues.size()); final Extension ext = file.getExtensions().get(0); assertEquals("List", ext.getReturnType(null, ec, null).getName()); } public final void testAmbigous() { final ExtensionFile file = parse("" + "doStuff("+TypeA.class.getName().replaceAll("\\.", "::")+" this) : true; " + "doStuff("+TypeC.class.getName().replaceAll("\\.", "::")+" this) : false;" + "bla("+TypeB.class.getName().replaceAll("\\.", "::")+" this) : this.doStuff();"); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(1, issues.size()); } /** * Tests the import statement with a Java package name from a used type. * It is expected that no issues arise. */ public final void testNamespaceImport_Success() { final ExtensionFile file = parse("" + "import "+TypeA.class.getPackage().getName().replaceAll("\\.", "::")+"; " + "doStuff(TypeA this) : true; " ); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(0, issues.size()); } /** * Test the import statement with an invalid namespace. * It is expected that this results in an analyzation issue. */ public final void testNamespaceImport_InvalidImport() { final ExtensionFile file = parse("" + "import x::y; " + "doStuff("+TypeA.class.getName().replaceAll("\\.", "::")+" this) : true; " ); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(1, issues.size()); assertTrue(issues.iterator().next().isWarning()); } /** * Test the import statement with an unused namespace. * It is expected that this results in an analyzation issue. */ public final void testNamespaceImport_Unused() { final ExtensionFile file = parse("" + "import "+TypeA.class.getPackage().getName().replaceAll("\\.", "::")+"; " ); ec = (ExecutionContextImpl) ec.cloneWithResource(file); file.analyze(ec, issues); assertEquals(1, issues.size()); assertTrue(issues.iterator().next().isWarning()); } public void testReexport() throws Exception { final ExtensionFile file = parse("extension org::eclipse::xtend::Reexporting; foo(String this) : doStuff(); "); file.analyze(ec, issues); System.out.println(issues); assertEquals(0,issues.size()); } public void testResolving() { if (!VersionComparator.isAtLeastVersion("1.6")) return; final ExtensionFile file = parse("import javax::lang::model::element;\n" + "test(TypeElement e) : e.typeParameters.first();\n"); file.analyze(ec, issues); System.out.println(issues); assertEquals(0, issues.size()); } public final void testMultipleCalls() { final ExtensionFile file = parse( "a() : 'A' ; \n" + "aa() : a() + 'B'; \n" + "ab() : a() + 'B'; \n" + "aaab() : aa() + ab(); \n" + "outer(): aaab();" ); file.analyze(ec, issues); dumpIssues(); assertEquals(0, issues.size()); } }