use of org.eclipse.ceylon.model.typechecker.model.Setter in project ceylon by eclipse.
the class DeclarationVisitor method checkForDuplicateDeclaration.
private static void checkForDuplicateDeclaration(Tree.Declaration that, Declaration model, Scope scope) {
String name = model.getName();
Unit unit = model.getUnit();
if (name != null) {
if (model instanceof Setter) {
Setter setter = (Setter) model;
checkGetterForSetter(that, setter, scope);
} else {
// this isn't the correct scope for declaration
// which follow an assertion, since it misses
// condition scopes, so use the argument scope
// Scope scope = model.getContainer();
boolean isControl;
do {
Declaration member = scope.getDirectMember(name, null, false);
if (member != null && member != model) {
boolean dup = false;
boolean possibleOverloadedMethod = member instanceof Function && model instanceof Function && scope instanceof ClassOrInterface && !member.isNative() && member.isShared() && model.isShared();
boolean legalOverloadedMethod = possibleOverloadedMethod;
if (legalOverloadedMethod) {
// anticipate that it might be
// an overloaded method - then
// further checking happens in
// RefinementVisitor
initFunctionOverload((Function) model, (Function) member, scope, unit);
} else if (canBeNative(member) && canBeNative(model) && model.isNative()) {
// just to make sure no error
// gets reported
} else {
dup = true;
if (possibleOverloadedMethod) {
// it as overloading anyway
if (initFunctionOverload((Function) model, (Function) member, scope, unit)) {
that.addError("duplicate declaration: the name '" + name + "' is not unique in this scope");
}
} else {
that.addError("duplicate declaration: the name '" + name + "' is not unique in this scope");
}
}
if (dup) {
unit.getDuplicateDeclarations().add(member);
}
}
isControl = scope instanceof ControlBlock;
scope = scope.getContainer();
} while (isControl);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Setter 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("};}");
}
use of org.eclipse.ceylon.model.typechecker.model.Setter in project ceylon by eclipse.
the class ValueVisitor method visit.
@Override
public void visit(Tree.Declaration that) {
Declaration dm = that.getDeclarationModel();
if (dm == declaration.getContainer() || dm == declaration || (dm instanceof Setter && ((Setter) dm).getGetter() == declaration)) {
inCapturingScope = false;
}
super.visit(that);
}
use of org.eclipse.ceylon.model.typechecker.model.Setter in project ceylon by eclipse.
the class MethodOrValueReferenceVisitor method visit.
@Override
public void visit(Tree.Declaration that) {
Declaration dm = that.getDeclarationModel();
if (dm == declaration.getContainer() || (Decl.equal(dm, declaration) && !isClassWithConstructorMember(declaration)) || (dm instanceof Setter && ((Setter) dm).getGetter() == declaration)) {
if (!isCapturableMplParameter(declaration)) {
this.inCapturingScope = false;
}
}
super.visit(that);
}
use of org.eclipse.ceylon.model.typechecker.model.Setter in project ceylon by eclipse.
the class ClassTransformer method concreteMembersFromSuperinterfaces.
/**
* Generates companion fields ($Foo$impl) and methods
*/
private void concreteMembersFromSuperinterfaces(final Class model, ClassDefinitionBuilder classBuilder, Type satisfiedType, Set<Interface> satisfiedInterfaces) {
satisfiedType = satisfiedType.resolveAliases();
Interface iface = (Interface) satisfiedType.getDeclaration();
if (satisfiedInterfaces.contains(iface) || iface.isIdentifiable()) {
return;
}
// then don't instantiate it...
if (hasImpl(iface)) {
// ... otherwise for each satisfied interface,
// instantiate an instance of the
// companion class in the constructor and assign it to a
// $Interface$impl field
transformInstantiateCompanions(classBuilder, model, iface, satisfiedType);
}
if (!ModelUtil.isCeylonDeclaration(iface)) {
// let's not try to implement CMI for Java interfaces
return;
}
// For each super interface
for (Declaration member : sortedMembers(iface.getMembers())) {
if (member instanceof Class) {
Class klass = (Class) member;
final Type typedMember = satisfiedType.getTypeMember(klass, Collections.<Type>emptyList());
if (Strategy.generateInstantiator(member) && !klass.hasConstructors() && !model.isFormal() && needsCompanionDelegate(model, typedMember) && model.getDirectMember(member.getName(), null, false) == null) {
// instantiator method implementation
generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, null, model.getType(), !member.isFormal());
}
if (klass.hasConstructors()) {
for (Declaration m : klass.getMembers()) {
if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
Constructor ctor = (Constructor) m;
generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, ctor, model.getType(), true);
}
}
}
}
// type aliases are on the $impl class
if (member instanceof TypeAlias)
continue;
if (Strategy.onlyOnCompanion(member)) {
// (they're just private methods on the $impl)
continue;
}
if (member instanceof Function) {
Function method = (Function) member;
final TypedReference typedMember = satisfiedType.getTypedMember(method, typesOfTypeParameters(method.getTypeParameters()));
Declaration sub = (Declaration) model.getMember(method.getName(), getSignatureIfRequired(typedMember), false, true);
if (sub instanceof Function) /* && !sub.isAbstraction()*/
{
Function subMethod = (Function) sub;
if (subMethod.getParameterLists().isEmpty()) {
continue;
}
java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, subMethod);
// final TypedReference refinedTypedMember = model.getType().getTypedMember(subMethod, Collections.<Type>emptyList());
final java.util.List<TypeParameter> typeParameters = subMethod.getTypeParameters();
final java.util.List<Parameter> parameters = subMethod.getFirstParameterList().getParameters();
boolean hasOverloads = false;
if (!satisfiedInterfaces.contains((Interface) method.getContainer())) {
for (Parameter param : parameters) {
if (Strategy.hasDefaultParameterValueMethod(param) && CodegenUtil.getTopmostRefinedDeclaration(param.getModel()).getContainer().equals(member)) {
final TypedReference typedParameter = typedMember.getTypedParameter(param);
// If that method has a defaulted parameter,
// we need to generate a default value method
// which also delegates to the $impl
final MethodDefinitionBuilder defaultValueDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().defaultValueMethodBridge(), typeParameters, producedTypeParameterBounds, typedParameter.getFullType(), Naming.getDefaultedParamMethodName(method, param), parameters.subList(0, parameters.indexOf(param)), param.getModel().getTypeErased(), null, param);
classBuilder.method(defaultValueDelegate);
}
if (Strategy.hasDefaultParameterOverload(param)) {
if ((method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(new DaoThis((Tree.AnyMethod) null, null), MethodDefinitionBuilder.method(this, subMethod), typedMember, true).makeOverload(subMethod.getFirstParameterList(), param, typeParameters);
classBuilder.method(overload);
}
hasOverloads = true;
}
}
}
// delegating to the $impl instance
if (needsCompanionDelegate(model, typedMember)) {
final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().methodBridge(method), typeParameters, producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, null);
classBuilder.method(concreteMemberDelegate);
}
if (hasOverloads && (method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
final MethodDefinitionBuilder canonicalMethod = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().canonicalMethodBridge(), subMethod.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), Naming.selector(method, Naming.NA_CANONICAL_METHOD), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), naming.selector(method), null);
classBuilder.method(canonicalMethod);
}
}
} else if (member instanceof Value || member instanceof Setter) {
TypedDeclaration attr = (TypedDeclaration) member;
final TypedReference typedMember = satisfiedType.getTypedMember(attr, null);
if (needsCompanionDelegate(model, typedMember)) {
Setter setter = (member instanceof Setter) ? (Setter) member : null;
if (member instanceof Value) {
Value getter = (Value) member;
if (member instanceof JavaBeanValue) {
setter = ((Value) member).getSetter();
}
final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().getterBridge(getter), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(getter), Collections.<Parameter>emptyList(), getter.getTypeErased(), null, null);
classBuilder.method(getterDelegate);
}
if (setter != null) {
final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(iface, satisfiedType.getTypedMember(setter, null), model.getType(), modifierTransformation().setterBridge(setter), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(setter.getParameter()), setter.getTypeErased(), null, null);
classBuilder.method(setterDelegate);
}
if (Decl.isValue(member) && ((Value) attr).isVariable()) {
// $impl to delegate to
throw new BugException("assertion failed: " + member.getQualifiedNameString() + " was unexpectedly a variable value");
}
}
} else {
Reference typedMember = member instanceof TypeDeclaration ? satisfiedType.getTypeMember((TypeDeclaration) member, Collections.<Type>emptyList()) : satisfiedType.getTypedMember((TypedDeclaration) member, Collections.<Type>emptyList());
if (needsCompanionDelegate(model, typedMember)) {
throw new BugException("unhandled concrete interface member " + member.getQualifiedNameString() + " " + member.getClass());
}
}
}
// Add $impl instances for the whole interface hierarchy
satisfiedInterfaces.add(iface);
for (Type sat : iface.getSatisfiedTypes()) {
sat = model.getType().getSupertype(sat.getDeclaration());
concreteMembersFromSuperinterfaces(model, classBuilder, sat, satisfiedInterfaces);
}
}
Aggregations