Search in sources :

Example 46 with FunctionOrValue

use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.

the class TypeArgumentVisitor method visit.

@Override
public void visit(Tree.TypedDeclaration that) {
    TypedDeclaration dec = that.getDeclarationModel();
    if (!(that instanceof Tree.Variable)) {
        check(that.getType(), dec.isVariable() || dec.isLate(), dec);
    }
    if (dec.isParameter()) {
        flip();
        boolean topLevel = // i.e. toplevel parameter in a parameter declaration
        parameterizedDeclaration == null;
        if (topLevel) {
            // TODO: to fix #1378 don't do this when the
            // parameter dec occurs in any parameter
            // list other than the first parameter
            // list of the function
            FunctionOrValue fov = (FunctionOrValue) dec;
            parameterizedDeclaration = fov.getInitializerParameter().getDeclaration();
        }
        check(that.getType(), false, parameterizedDeclaration);
        super.visit(that);
        if (topLevel) {
            parameterizedDeclaration = null;
        }
        flip();
    } else {
        super.visit(that);
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 47 with FunctionOrValue

use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.

the class AnnotationVisitor method checkAnnotationArgument.

/**
 * Checks that the given expression is a valid
 * annotation argument
 * (literal, tuple, annotation invocation etc)
 */
private void checkAnnotationArgument(Functional a, Tree.Expression e) {
    if (e != null) {
        Tree.Term term = e.getTerm();
        if (term instanceof Tree.Literal) {
        // ok
        } else if (term instanceof Tree.NegativeOp && ((Tree.NegativeOp) term).getTerm() instanceof Tree.Literal) {
        // ok
        } else if (term instanceof Tree.MetaLiteral) {
        // ok
        } else if (term instanceof Tree.Tuple) {
            Tree.Tuple tuple = (Tree.Tuple) term;
            Tree.SequencedArgument sa = tuple.getSequencedArgument();
            if (sa != null) {
                for (Tree.PositionalArgument arg : sa.getPositionalArguments()) {
                    if (arg instanceof Tree.ListedArgument) {
                        Tree.ListedArgument la = (Tree.ListedArgument) arg;
                        Tree.Expression expression = la.getExpression();
                        if (expression != null) {
                            checkAnnotationArgument(a, expression);
                        }
                    } else {
                        e.addError("illegal annotation argument: must be a literal value, metamodel reference, annotation instantiation, or parameter reference");
                    }
                }
            }
        } else if (term instanceof Tree.SequenceEnumeration) {
            Tree.SequenceEnumeration se = (Tree.SequenceEnumeration) term;
            Tree.SequencedArgument sa = se.getSequencedArgument();
            if (sa != null) {
                for (Tree.PositionalArgument arg : sa.getPositionalArguments()) {
                    if (arg instanceof Tree.ListedArgument) {
                        Tree.ListedArgument la = (Tree.ListedArgument) arg;
                        Tree.Expression expression = la.getExpression();
                        if (expression != null) {
                            checkAnnotationArgument(a, expression);
                        }
                    } else {
                        e.addError("illegal annotation argument: must be a literal value, metamodel reference, annotation instantiation, or parameter reference");
                    }
                }
            }
        } else if (term instanceof Tree.InvocationExpression) {
            checkAnnotationInstantiation(a, e, "illegal annotation argument: must be a literal value, metamodel reference, annotation instantiation, or parameter reference");
        } else if (term instanceof Tree.BaseMemberExpression) {
            Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) term;
            Declaration d = bme.getDeclaration();
            if (a != null && d != null && d.isParameter()) {
                FunctionOrValue mv = (FunctionOrValue) d;
                Parameter p = mv.getInitializerParameter();
                if (!p.getDeclaration().equals(a)) {
                    e.addError("illegal annotation argument: must be a reference to a parameter of the annotation");
                }
            } else if (d instanceof Value && (((Value) d).isEnumValue() || ((Value) d).getTypeDeclaration().isObjectClass())) {
            // ok
            } else if (d != null && d.isStatic()) {
            // ok
            } else {
                e.addError("illegal annotation argument: must be a literal value, metamodel reference, annotation instantiation, or parameter reference");
            }
        } else if (term instanceof Tree.QualifiedMemberExpression) {
            Tree.QualifiedMemberExpression qme = (Tree.QualifiedMemberExpression) term;
            Declaration d = qme.getDeclaration();
            if (d != null && !d.isStatic()) {
                e.addError("illegal annotation argument: must be a literal value, metamodel reference, annotation instantiation, or parameter reference");
            } else {
                Tree.Primary p = qme.getPrimary();
                while (!(p instanceof Tree.BaseTypeExpression)) {
                    if (p instanceof Tree.QualifiedTypeExpression) {
                        Tree.QualifiedTypeExpression qte = (Tree.QualifiedTypeExpression) p;
                        p = qte.getPrimary();
                    } else {
                        e.addError("illegal annotation argument: must be a literal value, metamodel reference, annotation instantiation, or parameter reference");
                        break;
                    }
                }
            }
        } else {
            e.addError("illegal annotation argument: must be a literal value, metamodel reference, annotation instantiation, or parameter reference");
        }
    }
}
Also used : Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 48 with FunctionOrValue

use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.

the class ExpressionVisitor method checkAliasArg.

private void checkAliasArg(Parameter param, Tree.Expression e) {
    if (e != null && param != null) {
        FunctionOrValue p = param.getModel();
        if (p != null) {
            Tree.Term term = e.getTerm();
            if (term instanceof Tree.BaseMemberExpression) {
                Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) term;
                Declaration d = bme.getDeclaration();
                if (d != null && !d.equals(p)) {
                    e.addUnsupportedError("argument must be a parameter reference to " + paramdesc(param));
                }
            } else {
                e.addUnsupportedError("argument must be a parameter reference to " + paramdesc(param));
            }
        }
    }
}
Also used : CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TreeUtil.isEffectivelyBaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.isEffectivelyBaseMemberExpression) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 49 with FunctionOrValue

use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.

the class ModelLoaderTests method functionalParameterParameterNames.

@Test
public void functionalParameterParameterNames() {
    compile("FunctionalParameterParameterNames.ceylon");
    try {
        verifyCompilerClassLoading("functionalparameterparameternamestest.ceylon", new RunnableTest() {

            @Override
            public void test(ModelLoader loader) {
                Module mod = loader.getLoadedModule(moduleForJavaModelLoading(), moduleVersionForJavaModelLoading());
                Assert.assertNotNull(mod);
                Package p = mod.getDirectPackage(packageForJavaModelLoading());
                Assert.assertNotNull(p);
                Declaration fpClass = p.getDirectMember("FunctionalParameterParameterNames", Collections.<Type>emptyList(), false);
                Assert.assertNotNull(fpClass);
                {
                    // functionalParameter
                    Function fp = (Function) fpClass.getDirectMember("functionalParameter", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals("Anything(Anything(String))", typeName(fp));
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertTrue(paramF.isDeclaredAnything());
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertTrue(modelF.isDeclaredVoid());
                    Assert.assertEquals("Anything(String)", typeName(modelF));
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramS = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("s", modelS.getName());
                    Assert.assertEquals("String", typeName(modelS));
                }
                {
                    // callableValueParameter
                    Function fp = (Function) fpClass.getDirectMember("callableValueParameter", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals("Anything(Anything(String))", typeName(fp));
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertFalse(paramF.isDeclaredAnything());
                    Assert.assertTrue(paramF.getModel() instanceof Value);
                    Value modelF = (Value) paramF.getModel();
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals("Anything(String)", typeName(modelF));
                }
                {
                    // functionalParameterNested
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterNested", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals("Anything(Anything(Anything(String)))", typeName(fp));
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.isDeclaredAnything());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertEquals("Anything(Anything(String))", typeName(modelF));
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertTrue(modelF.isDeclaredVoid());
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramF2 = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertTrue(paramF2.isDeclaredAnything());
                    Assert.assertEquals("f2", paramF2.getName());
                    Assert.assertTrue(paramF2.getModel() instanceof Function);
                    Function modelF2 = (Function) paramF2.getModel();
                    Assert.assertEquals("Anything(String)", typeName(modelF2));
                    Assert.assertEquals("f2", modelF2.getName());
                    Assert.assertTrue(modelF2.isDeclaredVoid());
                    Assert.assertEquals(1, modelF2.getParameterLists().size());
                    Assert.assertEquals(1, modelF2.getParameterLists().get(0).getParameters().size());
                    Parameter paramS = modelF2.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("s", modelS.getName());
                    Assert.assertEquals("String", typeName(modelS));
                }
                {
                    // functionalParameterNested2
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterNested2", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals("Anything(Anything(Anything(String, Anything(Boolean, Integer))))", typeName(fp));
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals("Anything(Anything(String, Anything(Boolean, Integer)))", typeName(modelF));
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramF2 = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("f2", paramF2.getName());
                    Assert.assertTrue(paramF2.getModel() instanceof Function);
                    Function modelF2 = (Function) paramF2.getModel();
                    Assert.assertEquals("Anything(String, Anything(Boolean, Integer))", typeName(modelF2));
                    Assert.assertEquals("f2", modelF2.getName());
                    Assert.assertEquals(1, modelF2.getParameterLists().size());
                    Assert.assertEquals(2, modelF2.getParameterLists().get(0).getParameters().size());
                    Parameter paramS = modelF2.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("String", typeName(modelS));
                    Assert.assertEquals("s", modelS.getName());
                    Parameter paramF3 = modelF2.getParameterLists().get(0).getParameters().get(1);
                    Assert.assertEquals("f3", paramF3.getName());
                    Assert.assertTrue(paramF3.getModel() instanceof Function);
                    Function modelF3 = (Function) paramF3.getModel();
                    Assert.assertEquals("Anything(Boolean, Integer)", typeName(modelF3));
                    Assert.assertEquals("f3", modelF3.getName());
                    Assert.assertEquals(1, modelF3.getParameterLists().size());
                    Assert.assertEquals(2, modelF3.getParameterLists().get(0).getParameters().size());
                    Parameter paramB1 = modelF3.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("b1", paramB1.getName());
                    Assert.assertTrue(paramB1.getModel() instanceof Value);
                    Value modelB1 = (Value) paramB1.getModel();
                    Assert.assertEquals("Boolean", typeName(modelB1));
                    Assert.assertEquals("b1", modelB1.getName());
                    Parameter paramI2 = modelF3.getParameterLists().get(0).getParameters().get(1);
                    Assert.assertEquals("i2", paramI2.getName());
                    Assert.assertTrue(paramI2.getModel() instanceof Value);
                    Value modelI2 = (Value) paramI2.getModel();
                    Assert.assertEquals("i2", modelI2.getName());
                    Assert.assertEquals("Integer", typeName(modelI2));
                }
                {
                    // functionalParameterMpl
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterMpl", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals("Anything(Anything(Integer)(String))", typeName(fp));
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertTrue(paramF.isDeclaredAnything());
                    Assert.assertEquals("mpl", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertTrue(modelF.isDeclaredVoid());
                    Assert.assertEquals("Anything(Integer)(String)", typeName(modelF));
                    Assert.assertEquals("mpl", modelF.getName());
                    Assert.assertEquals(2, modelF.getParameterLists().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(1).getParameters().size());
                    Parameter paramS = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("s", modelS.getName());
                    Assert.assertEquals("String", typeName(modelS));
                    Parameter paramS2 = modelF.getParameterLists().get(1).getParameters().get(0);
                    Assert.assertEquals("i2", paramS2.getName());
                    Assert.assertTrue(paramS2.getModel() instanceof Value);
                    Value modelS2 = (Value) paramS2.getModel();
                    Assert.assertEquals("i2", modelS2.getName());
                    Assert.assertEquals("Integer", typeName(modelS2));
                }
                {
                    // functionalParameterMpl2
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterMpl2", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Parameter paramMpl = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("mpl", paramMpl.getName());
                    Assert.assertTrue(paramMpl.getModel() instanceof Function);
                    Function modelMpl = (Function) paramMpl.getModel();
                    Assert.assertEquals("mpl", modelMpl.getName());
                    Assert.assertEquals(2, modelMpl.getParameterLists().size());
                    Assert.assertEquals(1, modelMpl.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals(1, modelMpl.getParameterLists().get(1).getParameters().size());
                    Parameter paramS = modelMpl.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("s", modelS.getName());
                    Assert.assertEquals("String", typeName(modelS));
                    Parameter paramF = modelMpl.getParameterLists().get(1).getParameters().get(0);
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(2, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramB1 = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("b1", paramB1.getName());
                    Assert.assertTrue(paramB1.getModel() instanceof Value);
                    Value modelB1 = (Value) paramB1.getModel();
                    Assert.assertEquals("b1", modelB1.getName());
                    Assert.assertEquals("Boolean", typeName(modelB1));
                    Parameter paramI2 = modelF.getParameterLists().get(0).getParameters().get(1);
                    Assert.assertEquals("i2", paramI2.getName());
                    Assert.assertTrue(paramI2.getModel() instanceof Value);
                    Value modelI2 = (Value) paramI2.getModel();
                    Assert.assertEquals("i2", modelI2.getName());
                    Assert.assertEquals("Integer", typeName(modelI2));
                }
                {
                    // functionalParameterMpl3
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterMpl3", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Parameter paramMpl = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("mpl", paramMpl.getName());
                    Assert.assertTrue(paramMpl.getModel() instanceof Function);
                    Function modelMpl = (Function) paramMpl.getModel();
                    Assert.assertEquals("mpl", modelMpl.getName());
                    Assert.assertEquals(2, modelMpl.getParameterLists().size());
                    Assert.assertEquals(1, modelMpl.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals(1, modelMpl.getParameterLists().get(1).getParameters().size());
                    Parameter paramF = modelMpl.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(2, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramB1 = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("b1", paramB1.getName());
                    Assert.assertTrue(paramB1.getModel() instanceof Value);
                    Value modelB1 = (Value) paramB1.getModel();
                    Assert.assertEquals("b1", modelB1.getName());
                    Assert.assertEquals("Boolean", typeName(modelB1));
                    Parameter paramI2 = modelF.getParameterLists().get(0).getParameters().get(1);
                    Assert.assertEquals("i2", paramI2.getName());
                    Assert.assertTrue(paramI2.getModel() instanceof Value);
                    Value modelI2 = (Value) paramI2.getModel();
                    Assert.assertEquals("i2", modelI2.getName());
                    Assert.assertEquals("Integer", typeName(modelI2));
                    Parameter paramS = modelMpl.getParameterLists().get(1).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("s", modelS.getName());
                    Assert.assertEquals("String", typeName(modelS));
                }
                {
                    // functionalParameterReturningCallable
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterReturningCallable", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals("Anything()", modelF.getType().asString());
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramS = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("s", modelS.getName());
                    Assert.assertEquals("String", modelS.getType().asString());
                }
                {
                    // functionalParameterReturningCallable
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterTakingCallable", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals("Anything", modelF.getType().asString());
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramF2 = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("f2", paramF2.getName());
                    Assert.assertTrue(paramF2.getModel() instanceof Value);
                    Value modelF2 = (Value) paramF2.getModel();
                    Assert.assertEquals("f2", modelF2.getName());
                    Assert.assertEquals("Anything(String)", modelF2.getType().asString());
                }
                {
                    // functionalParameterVariadicStar
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterVariadicStar", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals("Anything(Anything(String*))", typeName(fp));
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertTrue(paramF.isDeclaredAnything());
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertTrue(modelF.isDeclaredVoid());
                    Assert.assertEquals("Anything(String*)", typeName(modelF));
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramS = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.isSequenced());
                    Assert.assertFalse(paramS.isAtLeastOne());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("s", modelS.getName());
                    Assert.assertEquals("String[]", typeName(modelS));
                }
                {
                    // functionalParameterVariadicPlus
                    Function fp = (Function) fpClass.getDirectMember("functionalParameterVariadicPlus", null, false);
                    Assert.assertNotNull(fp);
                    Assert.assertEquals(1, fp.getParameterLists().size());
                    Assert.assertEquals(1, fp.getParameterLists().get(0).getParameters().size());
                    Assert.assertEquals("Anything(Anything(String+))", typeName(fp));
                    Parameter paramF = fp.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertTrue(paramF.isDeclaredAnything());
                    Assert.assertEquals("f", paramF.getName());
                    Assert.assertTrue(paramF.getModel() instanceof Function);
                    Function modelF = (Function) paramF.getModel();
                    Assert.assertTrue(modelF.isDeclaredVoid());
                    Assert.assertEquals("Anything(String+)", typeName(modelF));
                    Assert.assertEquals("f", modelF.getName());
                    Assert.assertEquals(1, modelF.getParameterLists().size());
                    Assert.assertEquals(1, modelF.getParameterLists().get(0).getParameters().size());
                    Parameter paramS = modelF.getParameterLists().get(0).getParameters().get(0);
                    Assert.assertEquals("s", paramS.getName());
                    Assert.assertTrue(paramS.isSequenced());
                    Assert.assertTrue(paramS.isAtLeastOne());
                    Assert.assertTrue(paramS.getModel() instanceof Value);
                    Value modelS = (Value) paramS.getModel();
                    Assert.assertEquals("s", modelS.getName());
                    Assert.assertEquals("[String+]", typeName(modelS));
                }
            }

            private String typeName(FunctionOrValue fp) {
                if (fp instanceof Function) {
                    return fp.appliedTypedReference(null, Collections.<Type>emptyList()).getFullType().asString();
                } else if (fp instanceof Value) {
                    return fp.getType().asString();
                }
                return null;
            }
        });
    } catch (RuntimeException e) {
        if (e.getCause() instanceof org.junit.ComparisonFailure) {
            throw (org.junit.ComparisonFailure) e.getCause();
        } else if (e.getCause() instanceof java.lang.AssertionError) {
            throw (java.lang.AssertionError) e.getCause();
        }
        throw e;
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) ModelLoader(org.eclipse.ceylon.model.loader.ModelLoader) CeylonModelLoader(org.eclipse.ceylon.compiler.java.loader.CeylonModelLoader) RuntimeModelLoader(org.eclipse.ceylon.compiler.java.runtime.model.RuntimeModelLoader) AbstractModelLoader(org.eclipse.ceylon.model.loader.AbstractModelLoader) DeclarationType(org.eclipse.ceylon.model.loader.ModelLoader.DeclarationType) Type(org.eclipse.ceylon.model.typechecker.model.Type) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Package(org.eclipse.ceylon.model.typechecker.model.Package) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Module(org.eclipse.ceylon.model.typechecker.model.Module) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Test(org.junit.Test)

Example 50 with FunctionOrValue

use of org.eclipse.ceylon.model.typechecker.model.FunctionOrValue in project ceylon by eclipse.

the class TypeUtils method encodeForRuntime.

public static void encodeForRuntime(final Node that, final Declaration d, final GenerateJsVisitor gen, final RuntimeMetamodelAnnotationGenerator annGen) {
    gen.out("function(){return{mod:$CCMM$");
    List<TypeParameter> tparms = d instanceof Generic ? d.getTypeParameters() : null;
    List<Type> satisfies = null;
    List<Type> caseTypes = null;
    if (d instanceof Class) {
        Class _cd = (Class) d;
        if (_cd.getExtendedType() != null) {
            gen.out(",'super':");
            metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), _cd.getExtendedType(), null, gen);
        }
        // Parameter types
        if (_cd.getParameterList() != null) {
            gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
            encodeParameterListForRuntime(false, that, _cd.getParameterList(), gen);
        }
        satisfies = _cd.getSatisfiedTypes();
        caseTypes = _cd.getCaseTypes();
    } else if (d instanceof Interface) {
        Interface _id = (Interface) d;
        satisfies = _id.getSatisfiedTypes();
        caseTypes = _id.getCaseTypes();
        if (_id.isAlias()) {
            ArrayList<Type> s2 = new ArrayList<>(satisfies.size() + 1);
            s2.add(_id.getExtendedType());
            s2.addAll(satisfies);
            satisfies = s2;
        }
    } else if (d instanceof FunctionOrValue) {
        gen.out(",", MetamodelGenerator.KEY_TYPE, ":");
        if (d instanceof Function && ((Function) d).getParameterLists().size() > 1) {
            Type callableType = ((Function) d).getTypedReference().getFullType();
            // This needs a new setting to resolve types but not type parameters
            metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), that.getUnit().getCallableReturnType(callableType), null, gen);
        } else {
            // This needs a new setting to resolve types but not type parameters
            metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), ((FunctionOrValue) d).getType(), null, gen);
        }
        if (d instanceof Function) {
            gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
            // Parameter types of the first parameter list
            encodeParameterListForRuntime(false, that, ((Function) d).getFirstParameterList(), gen);
            tparms = d.getTypeParameters();
        }
    } else if (d instanceof Constructor) {
        gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
        encodeParameterListForRuntime(false, that, ((Constructor) d).getFirstParameterList(), gen);
    }
    if (!d.isToplevel()) {
        // Find the first container that is a Declaration
        Declaration _cont = ModelUtil.getContainingDeclaration(d);
        // Skip over anonymous types/funs as well as local non-captured fields
        while (_cont.isAnonymous() || !(_cont.isToplevel() || _cont.isClassOrInterfaceMember() || _cont instanceof Value == false)) {
            // Neither do we skip classes, even if they're anonymous
            if ((_cont instanceof Value && (((Value) _cont).isJsCaptured())) || _cont instanceof Class) {
                break;
            }
            Declaration __d = ModelUtil.getContainingDeclaration(_cont);
            if (__d == null)
                break;
            _cont = __d;
        }
        gen.out(",$cont:");
        boolean generateName = true;
        if ((_cont.getName() != null && _cont.isAnonymous() && _cont instanceof Function) || (_cont instanceof Value && !((Value) _cont).isTransient())) {
            // Anon functions don't have metamodel so go up until we find a non-anon container
            Declaration _supercont = ModelUtil.getContainingDeclaration(_cont);
            while (_supercont != null && _supercont.getName() != null && _supercont.isAnonymous()) {
                _supercont = ModelUtil.getContainingDeclaration(_supercont);
            }
            if (_supercont == null) {
                // If the container is a package, add it because this isn't really toplevel
                generateName = false;
                gen.out("0");
            } else {
                _cont = _supercont;
            }
        }
        if (generateName) {
            if (_cont instanceof Value) {
                if (AttributeGenerator.defineAsProperty(_cont)) {
                    gen.qualify(that, _cont);
                }
                gen.out(gen.getNames().getter(_cont, true));
            } else if (_cont instanceof Setter) {
                gen.out("{setter:");
                if (AttributeGenerator.defineAsProperty(_cont)) {
                    gen.qualify(that, _cont);
                    gen.out(gen.getNames().getter(((Setter) _cont).getGetter(), true), ".set");
                } else {
                    gen.out(gen.getNames().setter(((Setter) _cont).getGetter()));
                }
                gen.out("}");
            } else {
                boolean inProto = gen.opts.isOptimize() && (_cont.getContainer() instanceof TypeDeclaration);
                final String path = gen.qualifiedPath(that, _cont, inProto);
                if (path != null && !path.isEmpty()) {
                    gen.out(path, ".");
                }
                final String contName = gen.getNames().name(_cont);
                gen.out(contName);
            }
        }
    }
    if (tparms != null && !tparms.isEmpty()) {
        gen.out(",", MetamodelGenerator.KEY_TYPE_PARAMS, ":{");
        encodeTypeParametersForRuntime(that, d, tparms, true, gen);
        gen.out("}");
    }
    if (satisfies != null && !satisfies.isEmpty()) {
        gen.out(",", MetamodelGenerator.KEY_SATISFIES, ":[");
        boolean first = true;
        for (Type st : satisfies) {
            if (!first)
                gen.out(",");
            first = false;
            metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), st, null, gen);
        }
        gen.out("]");
    }
    if (caseTypes != null && !caseTypes.isEmpty()) {
        gen.out(",of:[");
        boolean first = true;
        for (Type st : caseTypes) {
            // teeheehee
            final TypeDeclaration std = st.getDeclaration();
            if (!first)
                gen.out(",");
            first = false;
            if (ModelUtil.isConstructor(std)) {
                if (std.isAnonymous()) {
                    // Value constructor
                    gen.out(gen.getNames().name(d), ".", gen.getNames().valueConstructorName(std));
                } else {
                    gen.out("/*TODO callable constructor*/");
                }
            } else if (std.isAnonymous()) {
                if (std.isStatic()) {
                    gen.out(gen.getNames().name(ModelUtil.getContainingDeclaration(std)), ".$st$.", gen.getNames().objectName(std));
                } else {
                    gen.out(gen.getNames().getter(std, true));
                }
            } else {
                metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), st, null, gen);
            }
        }
        gen.out("]");
    }
    if (annGen != null) {
        annGen.generateAnnotations();
    }
    // Path to its model
    gen.out(",d:");
    outputModelPath(d, gen);
    gen.out("};}");
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Generic(org.eclipse.ceylon.model.typechecker.model.Generic) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ArrayList(java.util.ArrayList) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Aggregations

FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)65 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)28 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)27 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)26 Type (org.eclipse.ceylon.model.typechecker.model.Type)25 Value (org.eclipse.ceylon.model.typechecker.model.Value)24 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)22 Function (org.eclipse.ceylon.model.typechecker.model.Function)22 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)21 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)19 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)13 ArrayList (java.util.ArrayList)12 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)11 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)10 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)9 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)9 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)9 ModelUtil.genericFunctionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType)9 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)9 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)9