use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class ExpressionVisitor method resolveQualifiedMemberExpression.
private TypedDeclaration resolveQualifiedMemberExpression(Tree.QualifiedMemberExpression that, boolean error) {
Tree.Identifier id = that.getIdentifier();
boolean nameNonempty = id != null && !id.getText().equals("");
if (nameNonempty && checkMember(that)) {
Tree.Primary primary = that.getPrimary();
String name = name(id);
List<Type> signature = that.getSignature();
boolean spread = that.getEllipsis();
String container;
boolean ambiguous;
TypedDeclaration member;
Type pt;
if (primary instanceof Tree.Package) {
Package pack = unit.getPackage();
container = "package '" + pack.getNameAsString() + "'";
member = getPackageTypedDeclaration(name, signature, spread, unit);
ambiguous = false;
pt = null;
} else {
pt = primary.getTypeModel().resolveAliases();
TypeDeclaration d = getDeclaration(that, pt);
if (d instanceof Constructor) {
d = d.getExtendedType().getDeclaration();
}
container = "type '" + d.getName(unit) + "'";
Scope scope = that.getScope();
member = getTypedMember(d, name, signature, spread, unit, scope);
ambiguous = member == null && d.isMemberAmbiguous(name, unit, signature, spread);
if (member == null) {
container += memberCorrectionMessage(name, d, scope, unit, cancellable);
}
}
if (member == null) {
if (error) {
if (ambiguous) {
that.addError("method or attribute is ambiguous: '" + name + "' for " + container);
} else {
that.addError("method or attribute is not defined: '" + name + "' in " + container, 100);
unit.setUnresolvedReferences();
}
}
} else {
member = (TypedDeclaration) handleAbstractionOrHeader(member, that, error);
if (error) {
checkStaticPrimary(that, primary, member, pt);
}
that.setDeclaration(member);
resetSuperReference(that);
boolean selfReference = isSelfReference(primary);
if (!selfReference && !member.isShared()) {
member.setOtherInstanceAccess(true);
}
if (error) {
if (checkConcreteConstructor(member, that)) {
checkQualifiedVisibility(that, member, name, container, selfReference);
}
checkSuperMember(that, signature, spread);
}
}
return member;
} else {
return null;
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class InvocationGenerator method positionalInvocation.
private void positionalInvocation(final Tree.InvocationExpression that) {
final Tree.Primary typeArgSource = that.getPrimary();
final Tree.PositionalArgumentList argList = that.getPositionalArgumentList();
final Map<TypeParameter, Type> targs = getTypeArguments(typeArgSource);
if (gen.isInDynamicBlock() && typeArgSource instanceof Tree.BaseTypeExpression && ((Tree.BaseTypeExpression) typeArgSource).getDeclaration() == null) {
gen.out("(");
// Could be a dynamic object, or a Ceylon one
// We might need to call "new" so we need to get all the args to pass directly later
final List<String> argnames = generatePositionalArguments(typeArgSource, argList, argList.getPositionalArguments(), false, true);
if (!argnames.isEmpty()) {
gen.out(",");
}
final String fname = names.createTempVariable();
gen.out(fname, "=");
typeArgSource.visit(gen);
String theargs = "";
if (!argnames.isEmpty()) {
theargs = argnames.toString().substring(1);
theargs = theargs.substring(0, theargs.length() - 1);
}
gen.out(",", fname, ".$$===undefined?new ", fname, "(", theargs, "):", fname, "(", theargs, "))");
// TODO we lose type args for now
return;
} else {
final Tree.PositionalArgument lastArg = argList.getPositionalArguments().isEmpty() ? null : argList.getPositionalArguments().get(argList.getPositionalArguments().size() - 1);
boolean hasSpread = lastArg instanceof Tree.SpreadArgument && that.getUnit().isUnknownArgumentsCallable(that.getPrimary().getTypeModel()) && !typeArgSource.getTypeModel().isUnknown();
if (hasSpread) {
gen.out(gen.getClAlias(), "spread$2(");
}
if (typeArgSource instanceof Tree.BaseMemberExpression) {
final Tree.BaseMemberExpression _bme = (Tree.BaseMemberExpression) typeArgSource;
if (gen.isInDynamicBlock()) {
if (_bme.getDeclaration() == null || _bme.getDeclaration().isDynamic() || (_bme.getDeclaration() instanceof TypedDeclaration && ((TypedDeclaration) _bme.getDeclaration()).isDynamicallyTyped())) {
if (lastArg instanceof Tree.SpreadArgument && (lastArg.getTypeModel() == null || lastArg.getTypeModel().isUnknown())) {
BmeGenerator.generateBme(_bme, gen);
gen.out(".apply(0,");
if (argList.getPositionalArguments().size() == 1) {
generatePositionalArguments(typeArgSource, argList, argList.getPositionalArguments(), false, true);
} else {
gen.out("[");
ArrayList<Tree.PositionalArgument> subargs = new ArrayList<>(argList.getPositionalArguments().size());
subargs.addAll(argList.getPositionalArguments());
subargs.remove(subargs.size() - 1);
generatePositionalArguments(typeArgSource, argList, subargs, false, true);
gen.out("].concat(");
lastArg.visit(gen);
gen.out(")");
}
gen.out(")");
return;
}
} else if ("ceylon.language::print".equals(_bme.getDeclaration().getQualifiedNameString())) {
Tree.PositionalArgument printArg = that.getPositionalArgumentList().getPositionalArguments().get(0);
if (ModelUtil.isTypeUnknown(printArg.getTypeModel())) {
// #397
gen.out(gen.getClAlias(), "pndo$(");
printArg.visit(gen);
gen.out(")");
return;
}
}
}
BmeGenerator.generateBme(_bme, gen);
} else if (typeArgSource instanceof Tree.QualifiedTypeExpression) {
BmeGenerator.generateQte((Tree.QualifiedTypeExpression) typeArgSource, gen);
} else {
typeArgSource.visit(gen);
}
if (gen.opts.isOptimize() && (gen.getSuperMemberScope(typeArgSource) != null)) {
gen.out(".call(", names.self(ModelUtil.getContainingClassOrInterface(typeArgSource.getScope())));
if (!argList.getPositionalArguments().isEmpty()) {
gen.out(",");
}
} else if (hasSpread) {
gen.out(",");
} else {
gen.out("(");
}
// Check if args have params
boolean fillInParams = !argList.getPositionalArguments().isEmpty();
for (Tree.PositionalArgument arg : argList.getPositionalArguments()) {
fillInParams &= arg.getParameter() == null;
}
if (fillInParams) {
// Get the callable and try to assign params from there
Interface cd = that.getUnit().getCallableDeclaration();
final Type ed = that.getUnit().getEmptyType();
Class td = that.getUnit().getTupleDeclaration();
Type callable = typeArgSource.getTypeModel() == null ? null : typeArgSource.getTypeModel().getSupertype(cd);
if (callable != null) {
// This is a tuple with the arguments to the callable
// (can be union with empty if first param is defaulted)
Type callableArgs = callable.getTypeArgumentList().get(1);
boolean isUnion = false;
if (callableArgs.isUnion()) {
if (callableArgs.getCaseTypes().size() == 2) {
callableArgs = callableArgs.minus(ed);
}
isUnion = callableArgs.isUnion();
}
// This is the type of the first argument
boolean isSequenced = !(isUnion || td.equals(callableArgs.getDeclaration()));
Type argtype = isUnion ? callableArgs : callableArgs.isTypeParameter() || callableArgs.isEmpty() ? callableArgs : callableArgs.isSequence() || callableArgs.isSequential() ? callableArgs.getTypeArgumentList().get(0) : callableArgs.getTypeArgumentList().get(isSequenced ? 0 : 1);
Parameter p = null;
int c = 0;
for (Tree.PositionalArgument arg : argList.getPositionalArguments()) {
if (p == null) {
p = new Parameter();
p.setName("arg" + c);
p.setDeclaration(typeArgSource.getTypeModel().getDeclaration());
Value v = new Value();
Scope scope = that.getPositionalArgumentList().getScope();
v.setContainer(scope);
v.setScope(scope);
v.setType(argtype);
p.setModel(v);
if (callableArgs == null || isSequenced) {
p.setSequenced(true);
} else if (!isSequenced) {
Type next = isUnion ? null : callableArgs.getTypeArgumentList().get(2);
if (next != null && next.getSupertype(td) == null) {
// sequential if sequenced param
if (next.isUnion()) {
// empty|tuple
callableArgs = next.minus(ed);
isSequenced = !td.equals(callableArgs.getDeclaration());
argtype = callableArgs.getTypeArgumentList().get(isSequenced ? 0 : 1);
} else {
// we'll bet on sequential (if it's empty we don't care anyway)
argtype = next;
callableArgs = null;
}
} else {
// If it's a tuple then there are more params
callableArgs = next;
argtype = callableArgs == null ? null : callableArgs.getTypeArgumentList().get(1);
}
}
}
arg.setParameter(p);
c++;
if (!p.isSequenced()) {
p = null;
}
}
}
}
generatePositionalArguments(typeArgSource, argList, argList.getPositionalArguments(), false, false);
}
if (targs != null && !targs.isEmpty() && typeArgSource instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) typeArgSource).getDeclaration() instanceof Functional) {
if (argList.getPositionalArguments().size() > 0) {
gen.out(",");
}
Functional bmed = (Functional) ((Tree.MemberOrTypeExpression) typeArgSource).getDeclaration();
// If there are fewer arguments than there are parameters...
final int argsSize = argList.getPositionalArguments().size();
int paramArgDiff = bmed.getFirstParameterList().getParameters().size() - argsSize;
if (paramArgDiff > 0) {
final Tree.PositionalArgument parg = argsSize > 0 ? argList.getPositionalArguments().get(argsSize - 1) : null;
if (parg instanceof Tree.Comprehension || parg instanceof Tree.SpreadArgument) {
paramArgDiff--;
}
for (int i = 0; i < paramArgDiff; i++) {
gen.out("undefined,");
}
}
if (targs != null && !targs.isEmpty()) {
TypeUtils.printTypeArguments(typeArgSource, targs, gen, false, null);
}
}
gen.out(")");
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class MetamodelHelper method generateMemberLiteral.
static void generateMemberLiteral(final Tree.MemberLiteral that, final GenerateJsVisitor gen) {
final org.eclipse.ceylon.model.typechecker.model.Reference ref = that.getTarget();
Type ltype = that.getType() == null ? null : that.getType().getTypeModel().resolveAliases();
final Declaration d = ref.getDeclaration();
final Class anonClass = d.isMember() && d.getContainer() instanceof Class && ((Class) d.getContainer()).isAnonymous() ? (Class) d.getContainer() : null;
if (that instanceof Tree.FunctionLiteral || d instanceof Function) {
if (ModelUtil.isConstructor(d)) {
constructorLiteral(ref.getType(), TypeUtils.getConstructor(d), that, gen);
return;
}
gen.out(gen.getClAlias(), d.isMember() ? "AppliedMethod$jsint(" : "AppliedFunction$jsint(");
if (anonClass != null) {
gen.qualify(that, anonClass);
gen.out(gen.getNames().objectName(anonClass), ".");
} else if (ltype == null) {
gen.qualify(that, d);
} else {
if (ltype.isUnion() || ltype.isIntersection()) {
if (d.getContainer() instanceof TypeDeclaration) {
ltype = ((TypeDeclaration) d.getContainer()).getType();
} else if (d.getContainer() instanceof TypedDeclaration) {
ltype = ((TypedDeclaration) d.getContainer()).getType();
}
}
if (ltype.getDeclaration().isMember()) {
outputPathToDeclaration(that, ltype.getDeclaration(), gen);
} else {
gen.qualify(that, ltype.getDeclaration());
}
gen.out(gen.getNames().name(ltype.getDeclaration()));
gen.out(d.isStatic() ? ".$st$." : ".$$.prototype.");
}
if (d instanceof Value) {
gen.out(gen.getNames().getter(d, true), ",");
} else {
gen.out(gen.getNames().name(d), ",");
}
if (d.isMember()) {
if (that.getTypeArgumentList() != null) {
List<Type> typeModels = that.getTypeArgumentList().getTypeModels();
if (typeModels != null) {
gen.out("[");
boolean first = true;
for (Type targ : typeModels) {
if (first)
first = false;
else
gen.out(",");
gen.out(gen.getClAlias(), "typeLiteral$meta({Type$typeLiteral:");
TypeUtils.typeNameOrList(that, targ, gen, false);
gen.out("})");
}
gen.out("]");
gen.out(",");
} else {
gen.out("undefined,");
}
} else {
gen.out("undefined,");
}
TypeUtils.printTypeArguments(that, that.getTypeModel().getTypeArguments(), gen, false, that.getTypeModel().getVarianceOverrides());
} else {
TypeUtils.printTypeArguments(that, that.getTypeModel().getTypeArguments(), gen, false, that.getTypeModel().getVarianceOverrides());
if (ref.getTypeArguments() != null && !ref.getTypeArguments().isEmpty()) {
gen.out(",undefined,");
TypeUtils.printTypeArguments(that, ref.getTypeArguments(), gen, false, ref.getType().getVarianceOverrides());
}
}
gen.out(")");
} else if (that instanceof ValueLiteral || d instanceof Value) {
if (ModelUtil.isConstructor(d)) {
constructorLiteral(ref.getType(), TypeUtils.getConstructor(d), that, gen);
return;
}
Value vd = (Value) d;
if (vd.isMember()) {
gen.out(gen.getClAlias(), "$init$AppliedAttribute$meta$model()('");
gen.out(d.getName(), "',");
} else {
gen.out(gen.getClAlias(), "$init$AppliedValue$jsint()(undefined,");
}
if (anonClass != null) {
gen.qualify(that, anonClass);
gen.out(gen.getNames().objectName(anonClass), ".");
} else if (ltype == null) {
gen.qualify(that, d);
} else {
gen.qualify(that, ltype.getDeclaration());
gen.out(gen.getNames().name(ltype.getDeclaration()));
gen.out(d.isStatic() ? ".$st$." : ".$$.prototype.");
}
gen.out(gen.getNames().getter(vd, true), ",");
TypeUtils.printTypeArguments(that, that.getTypeModel().getTypeArguments(), gen, false, that.getTypeModel().getVarianceOverrides());
gen.out(")");
} else {
gen.out(gen.getClAlias(), "/*TODO:closed member literal*/typeLiteral$meta({Type$typeLiteral:");
gen.out("{t:");
if (ltype == null) {
gen.qualify(that, d);
} else {
gen.qualify(that, ltype.getDeclaration());
gen.out(gen.getNames().name(ltype.getDeclaration()));
gen.out(d.isStatic() ? ".$st$." : ".$$.prototype.");
}
gen.out(gen.getNames().name(d));
if (ltype != null && ltype.getTypeArguments() != null && !ltype.getTypeArguments().isEmpty()) {
gen.out(",a:");
TypeUtils.printTypeArguments(that, ltype.getTypeArguments(), gen, false, ltype.getVarianceOverrides());
}
gen.out("}})");
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class ClassImpl method getDeclaredConstructor.
@Override
@TypeParameters(@TypeParameter(value = "Arguments", satisfies = "ceylon.language::Sequential<ceylon.language::Anything>"))
@TypeInfo("ceylon.language.meta.model::CallableConstructor<Type,Arguments>|ceylon.language.meta.model::ValueConstructor<Type>|ceylon.language::Null")
public <Arguments extends Sequential<? extends Object>> java.lang.Object getDeclaredConstructor(@Ignore TypeDescriptor $reified$Arguments, @Name("name") String name) {
checkInit();
final ceylon.language.meta.declaration.Declaration ctor = ((ClassDeclarationImpl) declaration).getConstructorDeclaration(name);
if (ctor == null)
return null;
if (ctor instanceof CallableConstructorDeclaration) {
if (ctor instanceof ClassWithInitializerDeclarationConstructor) {
TypeDescriptor actualReifiedArguments = Metamodel.getTypeDescriptorForArguments(declaration.declaration.getUnit(), (Functional) ((ClassWithInitializerDeclarationConstructor) ctor).declaration, this.producedType);
Metamodel.checkReifiedTypeArgument("getDeclaredConstructor", "CallableConstructor<$1,$2>", // // this line is bullshit since it's always true, but otherwise we can't substitute the error message above :(
Variance.OUT, this.producedType, $reifiedType, Variance.IN, Metamodel.getProducedType(actualReifiedArguments), $reified$Arguments);
ClassInitializerConstructor c = new ClassInitializerConstructor<>(this);
return c;
}
CallableConstructorDeclarationImpl callableCtor = (CallableConstructorDeclarationImpl) ctor;
org.eclipse.ceylon.model.typechecker.model.Type constructorType = callableCtor.constructor.appliedType(this.producedType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
// return new AppliedConstructor<Type,Args>(this.$reifiedType, actualReifiedArguments, this, constructorType, ctor, this.instance);
// Reference reference = ((Function)callableCtor.declaration).getReference();
Reference reference;
if (callableCtor.declaration instanceof Function) {
reference = ((Function) callableCtor.declaration).appliedTypedReference(producedType, null);
} else if (callableCtor.declaration instanceof org.eclipse.ceylon.model.typechecker.model.Class) {
reference = ((org.eclipse.ceylon.model.typechecker.model.Class) callableCtor.declaration).appliedReference(producedType, null);
} else if (callableCtor.declaration instanceof org.eclipse.ceylon.model.typechecker.model.Constructor) {
reference = ((org.eclipse.ceylon.model.typechecker.model.Constructor) callableCtor.declaration).appliedReference(producedType, null);
} else {
throw Metamodel.newModelError("Unexpect declaration " + callableCtor.declaration);
}
// anonymous classes don't have parameter lists
TypeDescriptor actualReifiedArguments = Metamodel.getTypeDescriptorForArguments(declaration.declaration.getUnit(), (Functional) callableCtor.declaration, reference);
// This is all very ugly but we're trying to make it cheaper and friendlier than just checking the full type and showing
// implementation types to the user, such as AppliedMemberClass
Metamodel.checkReifiedTypeArgument("getConstructor", "Constructor<$1,$2>", // this line is bullshit since it's always true, but otherwise we can't substitute the error message above :(
Variance.OUT, this.producedType, $reifiedType, Variance.IN, Metamodel.getProducedType(actualReifiedArguments), $reified$Arguments);
CallableConstructorImpl<Type, Sequential<? extends Object>> appliedConstructor = new CallableConstructorImpl<Type, Sequential<? extends java.lang.Object>>(this.$reifiedType, $reified$Arguments, reference, callableCtor, this, instance);
Metamodel.checkReifiedTypeArgument("apply", "CallableConstructor<$1,$2>", Variance.OUT, producedType, $reifiedType, Variance.IN, Metamodel.getProducedTypeForArguments(declaration.declaration.getUnit(), (Functional) callableCtor.declaration, reference), $reified$Arguments);
return appliedConstructor;
} else if (ctor instanceof ValueConstructorDeclaration) {
ValueConstructorDeclarationImpl callableCtor = (ValueConstructorDeclarationImpl) ctor;
org.eclipse.ceylon.model.typechecker.model.Type constructorType = callableCtor.constructor.appliedType(this.producedType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
TypedDeclaration val = (TypedDeclaration) callableCtor.constructor.getContainer().getDirectMember(callableCtor.constructor.getName(), null, false);
return new ValueConstructorImpl<Type>(this.$reifiedType, callableCtor, val.getTypedReference(), this, instance);
} else {
throw new AssertionError("Constructor neither CallableConstructorDeclaration nor ValueConstructorDeclaration");
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.
the class MemberClassImpl method getDeclaredConstructor.
@Override
@TypeParameters({ @TypeParameter(value = "Arguments", satisfies = "ceylon.language::Anything[]") })
@TypeInfo("ceylon.language.meta.model::MemberClassCallableConstructor<Container,Type,Arguments>|ceylon.language.meta.model::MemberClassValueConstructor<Container,Type>|ceylon.language::Null")
public <Arguments extends Sequential<? extends Object>> java.lang.Object getDeclaredConstructor(@Ignore TypeDescriptor $reified$Arguments, @Name("name") String name) {
checkInit();
final ceylon.language.meta.declaration.Declaration ctor = ((ClassDeclarationImpl) declaration).getConstructorDeclaration(name);
if (ctor == null)
return null;
if (ctor instanceof CallableConstructorDeclaration) {
if (ctor instanceof ClassWithInitializerDeclarationConstructor) {
return new MemberClassInitializerConstructor<>(this.$reifiedContainer, this.$reifiedType, $reified$Arguments, this);
}
CallableConstructorDeclarationImpl callableCtor = (CallableConstructorDeclarationImpl) ctor;
// anonymous classes don't have parameter lists
// TypeDescriptor actualReifiedArguments = Metamodel.getTypeDescriptorForArguments(declaration.declaration.getUnit(), (Functional)callableCtor.constructor, this.producedType);
// This is all very ugly but we're trying to make it cheaper and friendlier than just checking the full type and showing
// implementation types to the user, such as AppliedMemberClass
// Metamodel.checkReifiedTypeArgument("getConstructor", "Constructor<$1,$2>",
// // this line is bullshit since it's always true, but otherwise we can't substitute the error message above :(
// Variance.OUT, this.producedType, $reifiedType,
// Variance.IN, Metamodel.getProducedType(actualReifiedArguments), $reifiedArguments);
// return new AppliedConstructor<Type,Args>(this.$reifiedType, actualReifiedArguments, this, constructorType, ctor, this.instance);
org.eclipse.ceylon.model.typechecker.model.Reference reference;
if (callableCtor.declaration instanceof Function) {
reference = ((Function) callableCtor.declaration).appliedTypedReference(producedType, null);
} else if (callableCtor.declaration instanceof org.eclipse.ceylon.model.typechecker.model.Class) {
reference = ((org.eclipse.ceylon.model.typechecker.model.Class) callableCtor.declaration).appliedReference(producedType, null);
} else if (callableCtor.declaration instanceof org.eclipse.ceylon.model.typechecker.model.Constructor) {
reference = ((org.eclipse.ceylon.model.typechecker.model.Constructor) callableCtor.declaration).appliedReference(producedType, null);
} else {
throw Metamodel.newModelError("Unexpect declaration " + callableCtor.declaration);
}
return new MemberClassCallableConstructorImpl<Container, Type, Sequential<? extends java.lang.Object>>($reifiedContainer, this.$reifiedType, $reified$Arguments, reference, callableCtor, this);
} else if (ctor instanceof ValueConstructorDeclaration) {
ValueConstructorDeclarationImpl callableCtor = (ValueConstructorDeclarationImpl) ctor;
// org.eclipse.ceylon.model.typechecker.model.Type constructorType = callableCtor.constructor.appliedType(this.producedType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList());
TypedDeclaration val = (TypedDeclaration) callableCtor.constructor.getContainer().getDirectMember(callableCtor.constructor.getName(), null, false);
return new MemberClassValueConstructorImpl<Container, Type>(// <Container>
$reifiedContainer, // <Get>
this.$reifiedType, callableCtor, val.getTypedReference(), this);
} else {
throw new AssertionError("Constructor neither CallableConstructorDeclaration nor ValueConstructorDeclaration");
}
/*checkInit();
final FreeConstructor ctor = (FreeConstructor)((FreeClass)declaration).getConstructorDeclaration(name);
if(ctor == null)
return null;
return new AppliedMemberClassConstructor($reifiedContainer, this.$reifiedType, reified$Arguments, this, ctor.constructor.appliedType(this.producedType, Collections.<org.eclipse.ceylon.model.typechecker.model.Type>emptyList()), ctor);*/
}
Aggregations