use of com.redhat.ceylon.model.typechecker.model.Declaration in project ceylon-compiler by ceylon.
the class MethodDefinitionBuilder method getNonWideningParam.
public NonWideningParam getNonWideningParam(TypedReference typedRef, WideningRules wideningRules) {
TypedDeclaration nonWideningDecl = null;
int flags = 0;
Type nonWideningType;
FunctionOrValue mov = (FunctionOrValue) typedRef.getDeclaration();
if (Decl.isValue(mov)) {
TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
nonWideningDecl = nonWideningTypedRef.getDeclaration();
} else {
// Stef: So here's the thing. I know this is wrong for Function where we should do getFullType(), BUT
// lots of methods call this and then feed the output into AT.makeJavaType(TypedDeclaration typeDecl, Type type, int flags)
// which adds the Callable type, so if we fix it here we have to remove it from there and there's lots of callers of that
// function which rely on its behaviour and frankly I've had enough of this refactoring, so a few callers of this function
// have to add the Callable back. It sucks, yeah, but so far it works, which is amazing enough that I don't want to touch it
// any more. More ambitious/courageous people are welcome to fix this properly.
nonWideningType = typedRef.getType();
nonWideningDecl = mov;
}
if (!CodegenUtil.isUnBoxed(nonWideningDecl))
flags |= AbstractTransformer.JT_NO_PRIMITIVES;
// make sure we don't accidentally narrow value parameters that would be erased in the topmost declaration
if (wideningRules != WideningRules.NONE && mov instanceof Value) {
TypedDeclaration refinedParameter = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(mov);
// mixin bridge methods have the same rules as when refining stuff except they are their own refined decl
if (wideningRules == WideningRules.FOR_MIXIN || !Decl.equal(refinedParameter, mov)) {
Type refinedParameterType;
// in the refined parameter type
if (refinedParameter instanceof Function)
refinedParameterType = refinedParameter.appliedTypedReference(null, Collections.<Type>emptyList()).getFullType();
else
refinedParameterType = refinedParameter.getType();
// if the supertype method itself got erased to Object, we can't do better than this
if (gen.willEraseToObject(refinedParameterType) && !gen.willEraseToBestBounds(mov))
nonWideningType = gen.typeFact().getObjectType();
else if (CodegenUtil.isRaw(refinedParameter)) {
flags |= AbstractTransformer.JT_RAW;
} else {
flags |= AbstractTransformer.JT_NARROWED;
}
}
}
// keep in sync with gen.willEraseToBestBounds()
if (wideningRules != WideningRules.NONE && (gen.typeFact().isUnion(nonWideningType) || gen.typeFact().isIntersection(nonWideningType))) {
final Type refinedType = ((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(nonWideningDecl)).getType();
if (refinedType.isTypeParameter() && !refinedType.getSatisfiedTypes().isEmpty()) {
nonWideningType = refinedType.getSatisfiedTypes().get(0);
// Could be parameterized, and type param won't be in scope, so have to go raw
flags |= AbstractTransformer.JT_RAW;
}
}
// this is to be done on the parameter's containing method, to see if that method must have raw parameters
if (mov.isParameter() && mov.getContainer() instanceof Declaration && gen.rawParameters((Declaration) mov.getContainer())) {
flags |= AbstractTransformer.JT_RAW;
}
return new NonWideningParam(flags, nonWideningType, nonWideningDecl);
}
use of com.redhat.ceylon.model.typechecker.model.Declaration in project ceylon-compiler by ceylon.
the class Naming method appendTypeDeclaration.
private void appendTypeDeclaration(final TypeDeclaration decl, EnumSet<DeclNameFlag> flags, TypeDeclarationBuilder<?> typeDeclarationBuilder, Scope scope, final boolean last) {
if (scope instanceof Class || scope instanceof TypeAlias || (scope instanceof Constructor && (scope.equals(decl) || !Decl.isLocalNotInitializerScope(scope)))) {
TypeDeclaration klass = (TypeDeclaration) scope;
if (klass.isAnonymous() && !klass.isNamed())
typeDeclarationBuilder.clear();
typeDeclarationBuilder.append(escapeClassName(klass.getName() != null ? klass.getName() : ""));
if (Decl.isCeylon(klass)) {
if (flags.contains(DeclNameFlag.COMPANION) && Decl.isLocalNotInitializer(klass) && last) {
typeDeclarationBuilder.append(IMPL_POSTFIX);
} else if (flags.contains(DeclNameFlag.ANNOTATION) && last) {
typeDeclarationBuilder.append(ANNO_POSTFIX);
} else if (flags.contains(DeclNameFlag.ANNOTATIONS) && last) {
typeDeclarationBuilder.append(ANNOS_POSTFIX);
} else if (flags.contains(DeclNameFlag.DELEGATION) && last) {
typeDeclarationBuilder.append(DELEGATION_POSTFIX);
}
}
} else if (scope instanceof Interface) {
Interface iface = (Interface) scope;
typeDeclarationBuilder.append(iface.getName());
if (Decl.isCeylon(iface) && ((decl instanceof Class || decl instanceof Constructor || decl instanceof TypeAlias || scope instanceof Constructor) || flags.contains(DeclNameFlag.COMPANION))) {
typeDeclarationBuilder.append(IMPL_POSTFIX);
}
} else if (Decl.isLocalNotInitializerScope(scope)) {
if (flags.contains(DeclNameFlag.COMPANION) || !(decl instanceof Interface)) {
typeDeclarationBuilder.clear();
} else if (flags.contains(DeclNameFlag.QUALIFIED) || (decl instanceof Interface)) {
Scope nonLocal = scope;
while (!(nonLocal instanceof Declaration)) {
nonLocal = nonLocal.getContainer();
}
typeDeclarationBuilder.append(((Declaration) nonLocal).getPrefixedName());
if (!Decl.equalScopes(scope, nonLocal)) {
typeDeclarationBuilder.append('$');
typeDeclarationBuilder.append(getLocalId(scope));
}
if (decl instanceof Interface) {
typeDeclarationBuilder.append('$');
} else {
if (flags.contains(DeclNameFlag.QUALIFIED)) {
typeDeclarationBuilder.selectAppended();
} else {
typeDeclarationBuilder.clear();
}
}
}
return;
} else if (scope instanceof TypedDeclaration && ((Declaration) scope).isToplevel()) {
// nothing? that's just weird
}
if (!last) {
if (decl instanceof Interface && Decl.isCeylon((TypeDeclaration) decl) && !flags.contains(DeclNameFlag.COMPANION)) {
typeDeclarationBuilder.append('$');
} else if (decl instanceof Constructor && ((Class) decl.getContainer()).isMember() && decl.getContainer().equals(scope)) {
typeDeclarationBuilder.append('$');
} else {
if (flags.contains(DeclNameFlag.QUALIFIED)) {
typeDeclarationBuilder.selectAppended();
} else {
typeDeclarationBuilder.clear();
}
}
} else {
typeDeclarationBuilder.selectAppended();
}
return;
}
use of com.redhat.ceylon.model.typechecker.model.Declaration in project ceylon-compiler by ceylon.
the class NamedArgumentInvocation method transformPrimary.
protected TransformedInvocationPrimary transformPrimary(JCExpression primaryExpr, String selector) {
if (Decl.isJavaStaticOrInterfacePrimary(getPrimary())) {
Declaration methodOrClass = ((Tree.QualifiedMemberOrTypeExpression) getPrimary()).getDeclaration();
if (methodOrClass instanceof Function) {
return new TransformedInvocationPrimary(gen.naming.makeName((Function) methodOrClass, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED), null);
} else if (methodOrClass instanceof Class) {
return new TransformedInvocationPrimary(gen.makeJavaType(((Class) methodOrClass).getType(), JT_RAW | JT_NO_PRIMITIVES), null);
}
}
if (isMemberRefInvocation()) {
JCExpression callable = gen.expressionGen().transformMemberReference((Tree.QualifiedMemberOrTypeExpression) getPrimary(), (Tree.MemberOrTypeExpression) getQmePrimary());
// The callable is a Callable we generate ourselves, it can never be erased to Object so there's no need to unerase
selector = Naming.getCallableMethodName();
return new TransformedInvocationPrimary(callable, selector);
}
JCExpression actualPrimExpr;
if (getPrimary() instanceof Tree.QualifiedTypeExpression && ((Tree.QualifiedTypeExpression) getPrimary()).getPrimary() instanceof Tree.BaseTypeExpression && !Decl.isConstructor(getPrimaryDeclaration())) {
actualPrimExpr = gen.naming.makeQualifiedThis(primaryExpr);
} else {
actualPrimExpr = primaryExpr;
}
if (getPrimary() instanceof Tree.BaseTypeExpression) {
Tree.BaseTypeExpression type = (Tree.BaseTypeExpression) getPrimary();
Declaration declaration = type.getDeclaration();
if (Strategy.generateInstantiator(declaration)) {
if (Decl.withinInterface(declaration)) {
if (primaryExpr != null) {
// if we have some other primary then respect that
actualPrimExpr = primaryExpr;
} else {
// if the class being instantiated is
// within a class we expect the instantiation to be
// accessible from `this`, so use null
// otherwise we must be in an companion class, so we
// need to qualify the instantiator invocation with $this
actualPrimExpr = type.getScope().getInheritingDeclaration(declaration) instanceof Class ? null : gen.naming.makeQuotedThis();
}
} else if (declaration.isToplevel()) {
actualPrimExpr = null;
}
// if the decl is not toplevel (but the primary is a base type
// we must be invoking a member imported from an object
// in which case the qualifer is needed.
}
if (Decl.isConstructor(declaration)) {
selector = null;
}
} else {
if (getPrimary() instanceof Tree.QualifiedMemberOrTypeExpression) {
Tree.QualifiedMemberOrTypeExpression type = (Tree.QualifiedMemberOrTypeExpression) getPrimary();
Declaration declaration = type.getDeclaration();
if (Decl.isConstructor(declaration)) {
if (Decl.withinInterface(Decl.getConstructedClass(declaration))) {
if (Strategy.generateInstantiator(declaration)) {
actualPrimExpr = primaryExpr != null ? primaryExpr : gen.naming.makeQuotedThis();
} else {
actualPrimExpr = null;
}
}
}
} else if (getPrimary() instanceof Tree.BaseMemberOrTypeExpression) {
Tree.BaseMemberOrTypeExpression type = (Tree.BaseMemberOrTypeExpression) getPrimary();
Declaration declaration = type.getDeclaration();
if (Decl.isConstructor(declaration)) {
selector = null;
}
}
if (isIndirect()) {
if (getPrimaryDeclaration() != null && (Decl.isGetter(getPrimaryDeclaration()) || Decl.isToplevel(getPrimaryDeclaration()) || (Decl.isValueOrSharedOrCapturedParam(getPrimaryDeclaration()) && Decl.isCaptured(getPrimaryDeclaration()) && !Decl.isLocalNotInitializer(getPrimaryDeclaration())))) {
// We need to invoke the getter to obtain the Callable
actualPrimExpr = gen.make().Apply(null, gen.naming.makeQualIdent(primaryExpr, selector), List.<JCExpression>nil());
} else if (selector != null) {
actualPrimExpr = gen.naming.makeQualIdent(primaryExpr, selector);
} else if (getPrimaryDeclaration() == null || !((TypedDeclaration) getPrimaryDeclaration()).getType().isTypeConstructor()) {
actualPrimExpr = gen.naming.makeQualifiedName(primaryExpr, (TypedDeclaration) getPrimaryDeclaration(), Naming.NA_MEMBER);
}
actualPrimExpr = unboxCallableIfNecessary(actualPrimExpr, getPrimary());
if (gen.isVariadicCallable(getPrimary().getTypeModel())) {
selector = Naming.getCallableVariadicMethodName();
this.callable = true;
} else {
selector = Naming.getCallableMethodName();
this.callable = true;
}
// If it's indirect the primary might be erased
actualPrimExpr = gen.expressionGen().applyErasureAndBoxing(actualPrimExpr, getPrimary().getTypeModel(), getPrimary().getTypeErased(), // boxed
true, BoxingStrategy.BOXED, getPrimary().getTypeModel(), 0);
} else if ((getPrimaryDeclaration() instanceof Function && // i.e. functional parameter
((Function) getPrimaryDeclaration()).isParameter() && // not class member, or not shared/captured
(!JvmBackendUtil.createMethod((Function) getPrimaryDeclaration())) || // we need to access the Callable parameter, no the member method
gen.expressionGen().isWithinDefaultParameterExpression(getPrimaryDeclaration().getContainer()))) {
if (selector != null) {
actualPrimExpr = gen.naming.makeQualIdent(primaryExpr, selector);
} else {
actualPrimExpr = gen.naming.makeQualifiedName(primaryExpr, (TypedDeclaration) getPrimaryDeclaration(), Naming.NA_MEMBER);
}
actualPrimExpr = unboxCallableIfNecessary(actualPrimExpr, getPrimary());
if (gen.isVariadicCallable(getPrimary().getTypeModel())) {
selector = Naming.getCallableVariadicMethodName();
this.callable = true;
} else {
selector = Naming.getCallableMethodName();
this.callable = true;
}
}
}
return new TransformedInvocationPrimary(actualPrimExpr, selector);
}
use of com.redhat.ceylon.model.typechecker.model.Declaration in project ceylon-compiler by ceylon.
the class AbstractTransformer method makeReifiedTypeArgumentResolved.
private JCExpression makeReifiedTypeArgumentResolved(Type pt, boolean qualified) {
if (pt.isUnion()) {
// FIXME: refactor this shite
List<JCExpression> typeTestArguments = List.nil();
java.util.List<Type> typeParameters = pt.getCaseTypes();
if (typeParameters.size() == 2) {
Type alternative = null;
if (typeParameters.get(0).isEmpty())
alternative = typeParameters.get(1);
else if (typeParameters.get(1).isEmpty())
alternative = typeParameters.get(0);
if (alternative != null && alternative.isTuple()) {
JCExpression tupleType = makeTupleTypeDescriptor(alternative, true);
if (tupleType != null)
return tupleType;
}
}
for (int i = typeParameters.size() - 1; i >= 0; i--) {
typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
}
return make().Apply(null, makeSelect(makeTypeDescriptorType(), "union"), typeTestArguments);
} else if (pt.isIntersection()) {
List<JCExpression> typeTestArguments = List.nil();
java.util.List<Type> typeParameters = pt.getSatisfiedTypes();
for (int i = typeParameters.size() - 1; i >= 0; i--) {
typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
}
return make().Apply(null, makeSelect(makeTypeDescriptorType(), "intersection"), typeTestArguments);
} else if (pt.isNothing()) {
return makeNothingTypeDescriptor();
}
TypeDeclaration declaration = pt.getDeclaration();
if (declaration instanceof Constructor) {
pt = pt.getExtendedType();
declaration = pt.getDeclaration();
}
if (pt.isClassOrInterface()) {
if (declaration.isJavaEnum()) {
pt = pt.getExtendedType();
declaration = pt.getDeclaration();
}
// see if we have an alias for it
if (supportsReifiedAlias((ClassOrInterface) declaration)) {
JCExpression qualifier = naming.makeDeclarationName(declaration, DeclNameFlag.QUALIFIED);
return makeSelect(qualifier, naming.getTypeDescriptorAliasName());
}
if (pt.isTuple()) {
JCExpression tupleType = makeTupleTypeDescriptor(pt, false);
if (tupleType != null)
return tupleType;
}
// no alias, must build it
List<JCExpression> typeTestArguments = makeReifiedTypeArgumentsResolved(pt.getTypeArgumentList(), qualified);
JCExpression thisType = makeUnerasedClassLiteral(declaration);
// do we have variance overrides?
Map<TypeParameter, SiteVariance> varianceOverrides = pt.getVarianceOverrides();
if (!varianceOverrides.isEmpty()) {
// we need to pass them as second argument then, in an array
ListBuffer<JCExpression> varianceElements = new ListBuffer<JCExpression>();
for (TypeParameter typeParameter : declaration.getTypeParameters()) {
SiteVariance useSiteVariance = varianceOverrides.get(typeParameter);
String selector;
if (useSiteVariance != null) {
switch(useSiteVariance) {
case IN:
selector = "IN";
break;
case OUT:
selector = "OUT";
break;
default:
selector = "NONE";
break;
}
} else {
selector = "NONE";
}
JCExpression varianceElement = make().Select(makeIdent(syms().ceylonVarianceType), names().fromString(selector));
varianceElements.append(varianceElement);
}
JCNewArray varianceArray = make().NewArray(makeIdent(syms().ceylonVarianceType), List.<JCExpression>nil(), varianceElements.toList());
typeTestArguments = typeTestArguments.prepend(varianceArray);
}
typeTestArguments = typeTestArguments.prepend(thisType);
JCExpression classDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), "klass"), typeTestArguments);
Type qualifyingType = pt.getQualifyingType();
JCExpression containerType = null;
if (qualifyingType == null && // ignore qualifying types of static java declarations
(Decl.isCeylon(declaration) || !declaration.isStaticallyImportable())) {
// it may be contained in a function or value, and we want its type
Declaration enclosingDeclaration = getDeclarationContainer(declaration);
if (enclosingDeclaration instanceof TypedDeclaration)
containerType = makeTypedDeclarationTypeDescriptorResolved((TypedDeclaration) enclosingDeclaration);
else if (enclosingDeclaration instanceof TypeDeclaration) {
qualifyingType = ((TypeDeclaration) enclosingDeclaration).getType();
}
}
if (qualifyingType != null && qualifyingType.getDeclaration() instanceof Constructor) {
qualifyingType = qualifyingType.getQualifyingType();
}
if (qualifyingType != null) {
containerType = makeReifiedTypeArgumentResolved(qualifyingType, true);
}
if (containerType == null) {
return classDescriptor;
} else {
return make().Apply(null, makeSelect(makeTypeDescriptorType(), "member"), List.of(containerType, classDescriptor));
}
} else if (pt.isTypeParameter()) {
TypeParameter tp = (TypeParameter) declaration;
String name = naming.getTypeArgumentDescriptorName(tp);
if (!qualified || isTypeParameterSubstituted(tp))
return makeUnquotedIdent(name);
Scope container = tp.getContainer();
JCExpression qualifier = null;
if (container instanceof Class) {
qualifier = naming.makeQualifiedThis(makeJavaType(((Class) container).getType(), JT_RAW));
} else if (container instanceof Interface) {
qualifier = naming.makeQualifiedThis(makeJavaType(((Interface) container).getType(), JT_COMPANION | JT_RAW));
} else if (container instanceof Function) {
// name must be a unique name, as returned by getTypeArgumentDescriptorName
return makeUnquotedIdent(name);
} else {
throw BugException.unhandledCase(container);
}
return makeSelect(qualifier, name);
} else {
throw BugException.unhandledDeclarationCase(declaration);
}
}
use of com.redhat.ceylon.model.typechecker.model.Declaration in project ceylon-compiler by ceylon.
the class IndexApiDoc method writeIndexTable.
private void writeIndexTable(List<Declaration> declarations) throws IOException {
open("table id='api-index' class='table table-hover'");
open("tbody");
for (Declaration declaration : declarations) {
writeIndexRow(declaration);
}
close("tbody");
close("table");
}
Aggregations