package org.example.smalljava.tests; import com.google.inject.Inject; import org.eclipse.emf.common.util.EList; import org.eclipse.xtend2.lib.StringConcatenation; import org.eclipse.xtext.junit4.InjectWith; import org.eclipse.xtext.junit4.XtextRunner; import org.eclipse.xtext.junit4.util.ParseHelper; import org.eclipse.xtext.junit4.validation.ValidationTestHelper; import org.eclipse.xtext.xbase.lib.Conversions; import org.eclipse.xtext.xbase.lib.Exceptions; import org.eclipse.xtext.xbase.lib.Extension; import org.eclipse.xtext.xbase.lib.IterableExtensions; import org.eclipse.xtext.xbase.lib.ObjectExtensions; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; import org.example.smalljava.SmallJavaInjectorProvider; import org.example.smalljava.smallJava.SJAssignment; import org.example.smalljava.smallJava.SJClass; import org.example.smalljava.smallJava.SJExpression; import org.example.smalljava.smallJava.SJMemberSelection; import org.example.smalljava.smallJava.SJMethod; import org.example.smalljava.smallJava.SJMethodBody; import org.example.smalljava.smallJava.SJProgram; import org.example.smalljava.smallJava.SJReturn; import org.example.smalljava.smallJava.SJStatement; import org.example.smalljava.smallJava.SJVariableDeclaration; import org.example.smalljava.typing.SmallJavaTypeProvider; import org.example.smalljava.util.SmallJavaModelUtil; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(XtextRunner.class) @InjectWith(SmallJavaInjectorProvider.class) @SuppressWarnings("all") public class SmallJavaTypeProviderTest { @Inject @Extension private ParseHelper<SJProgram> _parseHelper; @Inject @Extension private ValidationTestHelper _validationTestHelper; @Inject @Extension private SmallJavaTypeProvider _smallJavaTypeProvider; private SJProgram assertType(final CharSequence testExp, final String expectedClassName) { try { StringConcatenation _builder = new StringConcatenation(); _builder.append("class R { public V v; }"); _builder.newLine(); _builder.append("class P extends R { public R m() { return null; } }"); _builder.newLine(); _builder.append("class V extends R { public N n; }"); _builder.newLine(); _builder.append("class N extends R {}"); _builder.newLine(); _builder.append("class F extends R {}"); _builder.newLine(); _builder.newLine(); _builder.append("class C extends R {"); _builder.newLine(); _builder.append("\t"); _builder.append("F f;"); _builder.newLine(); _builder.append("\t"); _builder.newLine(); _builder.append("\t"); _builder.append("R m(P p) {"); _builder.newLine(); _builder.append("\t\t"); _builder.append("V v = null;"); _builder.newLine(); _builder.append("\t\t"); _builder.append(testExp, "\t\t"); _builder.append(";"); _builder.newLineIfNotEmpty(); _builder.append("\t\t"); _builder.append("return null;"); _builder.newLine(); _builder.append("\t"); _builder.append("}"); _builder.newLine(); _builder.append("}"); _builder.newLine(); SJProgram _parse = this._parseHelper.parse(_builder); final Procedure1<SJProgram> _function = new Procedure1<SJProgram>() { @Override public void apply(final SJProgram it) { SmallJavaTypeProviderTest.this._validationTestHelper.assertNoErrors(it); EList<SJClass> _classes = it.getClasses(); SJClass _last = IterableExtensions.<SJClass>last(_classes); Iterable<SJMethod> _methods = SmallJavaModelUtil.methods(_last); SJMethod _last_1 = IterableExtensions.<SJMethod>last(_methods); SJMethodBody _body = _last_1.getBody(); EList<SJStatement> _statements = _body.getStatements(); SJStatement _get = _statements.get(1); SJClass _statementExpressionType = SmallJavaTypeProviderTest.this.statementExpressionType(_get); String _name = _statementExpressionType.getName(); Assert.assertEquals(expectedClassName, _name); } }; return ObjectExtensions.<SJProgram>operator_doubleArrow(_parse, _function); } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } } private SJClass statementExpressionType(final SJStatement s) { return this._smallJavaTypeProvider.typeFor(((SJExpression) s)); } @Test public void thisType() { this.assertType("this", "C"); } @Test public void paramRefType() { this.assertType("p", "P"); } @Test public void varRefType() { this.assertType("v", "V"); } @Test public void newType() { this.assertType("new N()", "N"); } @Test public void fieldSelectionType() { this.assertType("this.f", "F"); } @Test public void methodInvocationType() { this.assertType("this.m(new P())", "R"); } @Test public void complexExpressionType() { this.assertType("p.m().v.n", "N"); } @Test public void stringConstantType() { this.assertType("\"foo\"", "stringType"); } @Test public void intConstantType() { this.assertType("10", "intType"); } @Test public void boolConstantType() { this.assertType("true", "booleanType"); } @Test public void nullType() { this.assertType("null", "nullType"); } @Test public void testTypeForUnresolvedReferences() { try { StringConcatenation _builder = new StringConcatenation(); _builder.append("class C {"); _builder.newLine(); _builder.append("\t"); _builder.append("U m() {"); _builder.newLine(); _builder.append("\t\t"); _builder.append("f ; // unresolved symbol"); _builder.newLine(); _builder.append("\t\t"); _builder.append("this.n(); // unresolved method "); _builder.newLine(); _builder.append("\t\t"); _builder.append("this.f; // unresolved field"); _builder.newLine(); _builder.append("\t\t"); _builder.append("return null;"); _builder.newLine(); _builder.append("\t"); _builder.append("}"); _builder.newLine(); _builder.append("}"); _builder.newLine(); SJProgram _parse = this._parseHelper.parse(_builder); final Procedure1<SJProgram> _function = new Procedure1<SJProgram>() { @Override public void apply(final SJProgram it) { EList<SJClass> _classes = it.getClasses(); SJClass _head = IterableExtensions.<SJClass>head(_classes); Iterable<SJMethod> _methods = SmallJavaModelUtil.methods(_head); SJMethod _head_1 = IterableExtensions.<SJMethod>head(_methods); SJMethodBody _body = _head_1.getBody(); EList<SJStatement> _statements = _body.getStatements(); final Procedure1<EList<SJStatement>> _function = new Procedure1<EList<SJStatement>>() { @Override public void apply(final EList<SJStatement> it) { SJStatement _get = it.get(0); SJClass _statementExpressionType = SmallJavaTypeProviderTest.this.statementExpressionType(_get); Assert.assertNull(_statementExpressionType); SJStatement _get_1 = it.get(1); SJClass _statementExpressionType_1 = SmallJavaTypeProviderTest.this.statementExpressionType(_get_1); Assert.assertNull(_statementExpressionType_1); SJStatement _get_2 = it.get(2); SJClass _statementExpressionType_2 = SmallJavaTypeProviderTest.this.statementExpressionType(_get_2); Assert.assertNull(_statementExpressionType_2); } }; ObjectExtensions.<EList<SJStatement>>operator_doubleArrow(_statements, _function); } }; ObjectExtensions.<SJProgram>operator_doubleArrow(_parse, _function); } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } } private EList<SJStatement> testStatements(final CharSequence statement) { try { StringConcatenation _builder = new StringConcatenation(); _builder.append("class R { }"); _builder.newLine(); _builder.append("class P1 { }"); _builder.newLine(); _builder.append("class P2 { }"); _builder.newLine(); _builder.append("class V { }"); _builder.newLine(); _builder.append("class F { }"); _builder.newLine(); _builder.newLine(); _builder.append("class C {"); _builder.newLine(); _builder.append("\t"); _builder.append("F f;"); _builder.newLine(); _builder.append("\t"); _builder.append("R m(P1 p1, P2 p2) {"); _builder.newLine(); _builder.append("\t\t"); _builder.append(statement, "\t\t"); _builder.newLineIfNotEmpty(); _builder.append("\t\t"); _builder.append("return null;"); _builder.newLine(); _builder.append("\t"); _builder.append("}"); _builder.newLine(); _builder.append("}"); _builder.newLine(); SJProgram _parse = this._parseHelper.parse(_builder); EList<SJClass> _classes = _parse.getClasses(); SJClass _last = IterableExtensions.<SJClass>last(_classes); Iterable<SJMethod> _methods = SmallJavaModelUtil.methods(_last); SJMethod _last_1 = IterableExtensions.<SJMethod>last(_methods); SJMethodBody _body = _last_1.getBody(); return _body.getStatements(); } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } } private void assertExpectedType(final SJExpression exp, final String expectedClassName) { SJClass _expectedType = this._smallJavaTypeProvider.expectedType(exp); String _name = _expectedType.getName(); Assert.assertEquals(expectedClassName, _name); } @Test public void testVarDeclExpectedType() { StringConcatenation _builder = new StringConcatenation(); _builder.append("V v = null;"); EList<SJStatement> _testStatements = this.testStatements(_builder); SJStatement _head = IterableExtensions.<SJStatement>head(_testStatements); SJExpression _expression = ((SJVariableDeclaration) _head).getExpression(); this.assertExpectedType(_expression, "V"); } @Test public void testAssignmentExpectedType() { StringConcatenation _builder = new StringConcatenation(); _builder.append("this.f = null;"); EList<SJStatement> _testStatements = this.testStatements(_builder); SJStatement _head = IterableExtensions.<SJStatement>head(_testStatements); SJExpression _right = ((SJAssignment) _head).getRight(); this.assertExpectedType(_right, "F"); } @Test public void testReturnExpectedType() { EList<SJStatement> _testStatements = this.testStatements(""); SJStatement _last = IterableExtensions.<SJStatement>last(_testStatements); SJExpression _expression = ((SJReturn) _last).getExpression(); this.assertExpectedType(_expression, "R"); } @Test public void testMethodInvocationArgsExpectedType() { EList<SJStatement> _testStatements = this.testStatements("this.m(new P1(), new P2());"); SJStatement _head = IterableExtensions.<SJStatement>head(_testStatements); EList<SJExpression> _args = ((SJMemberSelection) _head).getArgs(); final Procedure1<EList<SJExpression>> _function = new Procedure1<EList<SJExpression>>() { @Override public void apply(final EList<SJExpression> it) { SJExpression _get = it.get(0); SmallJavaTypeProviderTest.this.assertExpectedType(_get, "P1"); SJExpression _get_1 = it.get(1); SmallJavaTypeProviderTest.this.assertExpectedType(_get_1, "P2"); } }; ObjectExtensions.<EList<SJExpression>>operator_doubleArrow(_args, _function); } @Test public void testStandaloneMemberSelectionExpectedType() { try { StringConcatenation _builder = new StringConcatenation(); _builder.append("class A {"); _builder.newLine(); _builder.append("\t"); _builder.append("A a;"); _builder.newLine(); _builder.append("\t"); _builder.append("A m() { this.a; this.m(); return null; }"); _builder.newLine(); _builder.append("}"); _builder.newLine(); SJProgram _parse = this._parseHelper.parse(_builder); final Procedure1<SJProgram> _function = new Procedure1<SJProgram>() { @Override public void apply(final SJProgram it) { SmallJavaTypeProviderTest.this._validationTestHelper.assertNoErrors(it); EList<SJClass> _classes = it.getClasses(); SJClass _head = IterableExtensions.<SJClass>head(_classes); Iterable<SJMethod> _methods = SmallJavaModelUtil.methods(_head); SJMethod _head_1 = IterableExtensions.<SJMethod>head(_methods); SJMethodBody _body = _head_1.getBody(); EList<SJStatement> _statements = _body.getStatements(); final Procedure1<EList<SJStatement>> _function = new Procedure1<EList<SJStatement>>() { @Override public void apply(final EList<SJStatement> it) { SJStatement _get = it.get(0); SJClass _expectedType = SmallJavaTypeProviderTest.this._smallJavaTypeProvider.expectedType(((SJExpression) _get)); Assert.assertNull(_expectedType); SJStatement _get_1 = it.get(1); SJClass _expectedType_1 = SmallJavaTypeProviderTest.this._smallJavaTypeProvider.expectedType(((SJExpression) _get_1)); Assert.assertNull(_expectedType_1); } }; ObjectExtensions.<EList<SJStatement>>operator_doubleArrow(_statements, _function); } }; ObjectExtensions.<SJProgram>operator_doubleArrow(_parse, _function); } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } } @Test public void testWrongMethodInvocationArgsExpectedType() { EList<SJStatement> _testStatements = this.testStatements("this.n(new P1(), new P2());"); SJStatement _head = IterableExtensions.<SJStatement>head(_testStatements); EList<SJExpression> _args = ((SJMemberSelection) _head).getArgs(); final Procedure1<EList<SJExpression>> _function = new Procedure1<EList<SJExpression>>() { @Override public void apply(final EList<SJExpression> it) { SJExpression _get = it.get(0); SJClass _expectedType = SmallJavaTypeProviderTest.this._smallJavaTypeProvider.expectedType(_get); Assert.assertNull(_expectedType); SJExpression _get_1 = it.get(1); SJClass _expectedType_1 = SmallJavaTypeProviderTest.this._smallJavaTypeProvider.expectedType(_get_1); Assert.assertNull(_expectedType_1); } }; ObjectExtensions.<EList<SJExpression>>operator_doubleArrow(_args, _function); EList<SJStatement> _testStatements_1 = this.testStatements("this.m(new P1(), new P2(), new P1());"); SJStatement _head_1 = IterableExtensions.<SJStatement>head(_testStatements_1); EList<SJExpression> _args_1 = ((SJMemberSelection) _head_1).getArgs(); SJExpression _get = _args_1.get(2); SJClass _expectedType = this._smallJavaTypeProvider.expectedType(_get); Assert.assertNull(_expectedType); } @Test public void testArgsTypesAsString() { try { StringConcatenation _builder = new StringConcatenation(); _builder.append("class A {}"); _builder.newLine(); _builder.append("class B {}"); _builder.newLine(); _builder.append("class C {"); _builder.newLine(); _builder.append("\t"); _builder.append("A m() { return this.m(); }"); _builder.newLine(); _builder.append("\t"); _builder.append("A n(B b, C c) { return this.n(new B(), new C()); }"); _builder.newLine(); _builder.append("\t"); _builder.append("A p(Foo b, C c) { return this.p(new Foo(), new C()); }"); _builder.newLine(); _builder.append("}"); SJProgram _parse = this._parseHelper.parse(_builder); EList<SJClass> _classes = _parse.getClasses(); SJClass _last = IterableExtensions.<SJClass>last(_classes); Iterable<SJMethod> _methods = SmallJavaModelUtil.methods(_last); final Procedure1<Iterable<SJMethod>> _function = new Procedure1<Iterable<SJMethod>>() { @Override public void apply(final Iterable<SJMethod> it) { SJMethod _get = ((SJMethod[])Conversions.unwrapArray(it, SJMethod.class))[0]; String _methodInvocationArgsTypesAsString = SmallJavaTypeProviderTest.this.methodInvocationArgsTypesAsString(_get); Assert.assertEquals("()", _methodInvocationArgsTypesAsString); SJMethod _get_1 = ((SJMethod[])Conversions.unwrapArray(it, SJMethod.class))[1]; String _methodInvocationArgsTypesAsString_1 = SmallJavaTypeProviderTest.this.methodInvocationArgsTypesAsString(_get_1); Assert.assertEquals("(B, C)", _methodInvocationArgsTypesAsString_1); SJMethod _get_2 = ((SJMethod[])Conversions.unwrapArray(it, SJMethod.class))[2]; String _methodInvocationArgsTypesAsString_2 = SmallJavaTypeProviderTest.this.methodInvocationArgsTypesAsString(_get_2); Assert.assertEquals("(null, C)", _methodInvocationArgsTypesAsString_2); } }; ObjectExtensions.<Iterable<SJMethod>>operator_doubleArrow(_methods, _function); } catch (Throwable _e) { throw Exceptions.sneakyThrow(_e); } } private String methodInvocationArgsTypesAsString(final SJMethod m) { SJReturn _returnStatement = SmallJavaModelUtil.returnStatement(m); SJExpression _expression = _returnStatement.getExpression(); return this._smallJavaTypeProvider.argsTypesAsStrings(((SJMemberSelection) _expression)); } }