use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class AbstractTransformer method nonWideningType.
Type nonWideningType(TypedReference declaration, TypedReference refinedDeclaration) {
final Reference pr;
if (declaration.equals(refinedDeclaration)) {
pr = declaration;
} else {
Type refinedType = refinedDeclaration.getType();
// since it may have changed name
if (refinedType.getDeclaration() instanceof TypeParameter && refinedType.getDeclaration().getContainer() instanceof Function) {
// find its index in the refined declaration
TypeParameter refinedTypeParameter = (TypeParameter) refinedType.getDeclaration();
Function refinedMethod = (Function) refinedTypeParameter.getContainer();
int i = 0;
for (TypeParameter tp : refinedMethod.getTypeParameters()) {
if (tp.getName().equals(refinedTypeParameter.getName()))
break;
i++;
}
if (i >= refinedMethod.getTypeParameters().size()) {
throw new BugException("can't find type parameter " + refinedTypeParameter.getName() + " in its container " + refinedMethod.getName());
}
// the refining method type parameter should be at the same index
if (declaration.getDeclaration() instanceof Function == false)
throw new BugException("refining declaration is not a method: " + declaration);
Function refiningMethod = (Function) declaration.getDeclaration();
if (i >= refiningMethod.getTypeParameters().size()) {
throw new BugException("refining method does not have enough type parameters to refine " + refinedMethod.getName());
}
pr = refiningMethod.getTypeParameters().get(i).getType();
} else {
pr = refinedType;
}
}
if (pr.getDeclaration() instanceof Functional && Decl.isMpl((Functional) pr.getDeclaration())) {
// the innermost Callable.
return getReturnTypeOfCallable(pr.getFullType());
}
return getPinnedType(declaration, pr.getType());
}
use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class BoxingDeclarationVisitor method setBoxingState.
private void setBoxingState(TypedDeclaration declaration, TypedDeclaration refinedDeclaration, Node that) {
Type type = declaration.getType();
if (type == null) {
// an error must have already been reported
return;
}
// fetch the real refined declaration if required
if (Decl.equal(declaration, refinedDeclaration) && declaration instanceof FunctionOrValue && ((FunctionOrValue) declaration).isParameter() && declaration.getContainer() instanceof Class) {
// maybe it is really inherited from a field?
FunctionOrValue methodOrValueForParam = (FunctionOrValue) declaration;
if (methodOrValueForParam != null) {
// make sure we get the refined version of that member
refinedDeclaration = (TypedDeclaration) methodOrValueForParam.getRefinedDeclaration();
}
}
// inherit underlying type constraints
if (!Decl.equal(refinedDeclaration, declaration)) {
// simple case
if (type.getUnderlyingType() == null && refinedDeclaration.getType() != null) {
if (type.isCached()) {
type = type.clone();
}
type.setUnderlyingType(refinedDeclaration.getType().getUnderlyingType());
declaration.setType(type);
}
// special case for variadics
if (Decl.isValueParameter(refinedDeclaration)) {
Parameter parameter = ((FunctionOrValue) refinedDeclaration).getInitializerParameter();
if (parameter.isSequenced()) {
// inherit the underlying type of the iterated type
Type refinedIteratedType = refinedDeclaration.getType().getTypeArgumentList().get(0);
if (refinedIteratedType.getUnderlyingType() != null) {
Type ourIteratedType = type.getTypeArgumentList().get(0);
if (ourIteratedType.getUnderlyingType() == null) {
if (ourIteratedType.isCached()) {
ourIteratedType = ourIteratedType.clone();
}
ourIteratedType.setUnderlyingType(refinedIteratedType.getUnderlyingType());
type.getTypeArgumentList().set(0, ourIteratedType);
// make sure we remove those types from the cache otherwise UGLY things happen
TypeCache cache = type.getDeclaration().getUnit().getCache();
if (cache != null) {
cache.remove(ourIteratedType);
cache.remove(type);
}
}
}
}
}
}
// abort if our boxing state has already been set
if (declaration.getUnboxed() != null)
return;
// functional parameter return values are always boxed if we're not creating a method for them
if (declaration instanceof Function && ((Function) declaration).isParameter() && !JvmBackendUtil.createMethod((Function) declaration)) {
declaration.setUnboxed(false);
return;
}
if (!Decl.equal(refinedDeclaration, declaration)) {
// make sure refined declarations have already been set
if (refinedDeclaration.getUnboxed() == null)
setBoxingState(refinedDeclaration, refinedDeclaration, that);
// inherit
declaration.setUnboxed(refinedDeclaration.getUnboxed());
} else if (declaration instanceof Function && Strategy.useBoxedVoid((Function) declaration) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
declaration.setUnboxed(false);
} else if ((isCeylonBasicType(type) || Decl.isUnboxedVoid(declaration)) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && (refinedDeclaration.getContainer() instanceof Declaration == false || !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration)) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
boolean unbox = !forceBoxedLocals || !(declaration instanceof Value) || !Decl.isLocal(declaration) || Decl.isParameter(declaration) || Decl.isTransient(declaration);
// until it's used later by user code
if (declaration.getOriginalDeclaration() != null && declaration.hasUncheckedNullType())
unbox = false;
declaration.setUnboxed(unbox);
} else if (Decl.isValueParameter(declaration) && CodegenUtil.isContainerFunctionalParameter(declaration) && JvmBackendUtil.createMethod((FunctionOrValue) declaration.getContainer())) {
Function functionalParameter = (Function) declaration.getContainer();
TypedDeclaration refinedFrom = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(functionalParameter, optimisedMethodSpecifiersToMethods);
if (Decl.equal(refinedFrom, functionalParameter)) {
// not a method return type (where void would be considered unboxed).
if (declaration.getUnit().getAnythingType().isExactly(declaration.getType()) || declaration.getUnit().isOptionalType(declaration.getType())) {
declaration.setUnboxed(false);
} else {
declaration.setUnboxed(true);
}
} else {
// make sure refined declarations have already been set
if (refinedFrom.getUnboxed() == null)
setBoxingState(refinedFrom, refinedFrom, that);
// inherit
declaration.setUnboxed(refinedFrom.getUnboxed());
}
} else {
declaration.setUnboxed(false);
}
// Any "@boxed" or "@unboxed" compiler annotation overrides
boxFromAnnotation(declaration, that);
}
use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class BoxingVisitor method hasTypeParameterWithConstraintsOutsideScopeResolved.
private boolean hasTypeParameterWithConstraintsOutsideScopeResolved(Type type, Scope scope) {
if (type == null)
return false;
if (type.isUnion()) {
java.util.List<Type> caseTypes = type.getCaseTypes();
for (Type pt : caseTypes) {
if (hasTypeParameterWithConstraintsOutsideScopeResolved(pt, scope))
return true;
}
return false;
}
if (type.isIntersection()) {
java.util.List<Type> satisfiedTypes = type.getSatisfiedTypes();
for (Type pt : satisfiedTypes) {
if (hasTypeParameterWithConstraintsOutsideScopeResolved(pt, scope))
return true;
}
return false;
}
TypeDeclaration declaration = type.getDeclaration();
if (declaration == null)
return false;
if (type.isTypeParameter()) {
// only look at it if it is defined outside our scope
Scope typeParameterScope = declaration.getContainer();
while (scope != null) {
if (Decl.equalScopes(scope, typeParameterScope))
return false;
scope = scope.getContainer();
}
TypeParameter tp = (TypeParameter) declaration;
Boolean nonErasedBounds = tp.hasNonErasedBounds();
if (nonErasedBounds == null)
visitTypeParameter(tp);
return nonErasedBounds != null ? nonErasedBounds.booleanValue() : false;
}
// now check its type parameters
for (Type pt : type.getTypeArgumentList()) {
if (hasTypeParameterWithConstraintsOutsideScopeResolved(pt, scope))
return true;
}
// no problem here
return false;
}
use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class CallableBuilder method buildTypeConstructor.
protected JCExpression buildTypeConstructor(Type callableType, JCNewClass callableInstance) {
JCExpression result;
// Wrap in an anonymous TypeConstructor subcla
MethodDefinitionBuilder rawApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.apply.toString());
rawApply.modifiers(Flags.PUBLIC);
rawApply.isOverride(true);
// for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
// apply.typeParameter(tp);
// }
rawApply.resultType(new TransformedType(gen.makeJavaType(callableType, AbstractTransformer.JT_RAW)));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
rawApply.parameter(pdb);
}
rawApply.body(List.<JCStatement>of(gen.make().Return(gen.make().Apply(null, gen.naming.makeUnquotedIdent(Naming.Unfix.$apply$.toString()), List.<JCExpression>of(gen.naming.makeUnquotedIdent("applied"))))));
MethodDefinitionBuilder typedApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.$apply$.toString());
typedApply.modifiers(Flags.PRIVATE);
// for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
// apply.typeParameter(tp);
// }
typedApply.resultType(new TransformedType(gen.makeJavaType(callableType)));
{
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
pdb.modifiers(Flags.FINAL);
pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
typedApply.parameter(pdb);
}
ListBuffer<JCTypeParameter> typeParameters = new ListBuffer<JCTypeParameter>();
for (TypeParameter typeParameter : Strategy.getEffectiveTypeParameters(typeModel.getDeclaration())) {
Type typeArgument = typeModel.getTypeArguments().get(typeParameter);
typeParameters.add(gen.makeTypeParameter(typeParameter, null));
typedApply.body(gen.makeVar(Flags.FINAL, gen.naming.getTypeArgumentDescriptorName(typeParameter), gen.make().Type(gen.syms().ceylonTypeDescriptorType), gen.make().Indexed(gen.makeUnquotedIdent("applied"), gen.make().Literal(typeModel.getTypeArgumentList().indexOf(typeArgument)))));
}
typedApply.body(gen.make().Return(callableInstance));
// typedApply.body(body.toList());
MethodDefinitionBuilder ctor = MethodDefinitionBuilder.constructor(gen, false);
ctor.body(gen.make().Exec(gen.make().Apply(null, gen.naming.makeSuper(), List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))))));
SyntheticName n = gen.naming.synthetic(typeModel.getDeclaration().getName());
JCClassDecl classDef = gen.make().ClassDef(gen.make().Modifiers(0, List.<JCAnnotation>nil()), // name,
n.asName(), typeParameters.toList(), // extending
gen.make().QualIdent(gen.syms().ceylonAbstractTypeConstructorType.tsym), // implementing,
List.<JCExpression>nil(), List.<JCTree>of(ctor.build(), rawApply.build(), typedApply.build()));
result = gen.make().LetExpr(List.<JCStatement>of(classDef), gen.make().NewClass(null, null, n.makeIdent(), List.<JCExpression>nil(), // List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))),
null));
return result;
}
use of org.eclipse.ceylon.model.typechecker.model.TypeParameter in project ceylon by eclipse.
the class ClassOrPackageDoc method writeTypeParameters.
protected final void writeTypeParameters(List<TypeParameter> typeParameters, Referenceable scope) throws IOException {
if (typeParameters != null && !typeParameters.isEmpty()) {
write("<");
write("<span class='type-parameter'>");
boolean first = true;
for (TypeParameter typeParam : typeParameters) {
if (first) {
first = false;
} else {
write(", ");
}
if (typeParam.isContravariant()) {
write("<span class='type-parameter-keyword'>in </span>");
}
if (typeParam.isCovariant()) {
write("<span class='type-parameter-keyword'>out </span>");
}
write(typeParam.getName());
if (typeParam.isDefaulted() && typeParam.getDefaultTypeArgument() != null) {
write("<span class='type-parameter'> = </span>");
write("<span class='type-parameter-value'>");
write(linkRenderer().to(typeParam.getDefaultTypeArgument()).useScope(scope).getLink());
write("</span>");
}
}
write("</span>");
write(">");
}
}
Aggregations