use of org.eclipse.ceylon.model.typechecker.model.Package in project ceylon by eclipse.
the class ExpressionTransformer method functionalParameterRequiresCallable.
/**
* Determines whether we need to generate an AbstractCallable when taking
* a method reference to a method that's declared as a FunctionalParameter
*/
private boolean functionalParameterRequiresCallable(Function functionalParameter, Tree.StaticMemberOrTypeExpression expr) {
if (!functionalParameter.isParameter()) {
throw new BugException();
}
boolean hasMethod = JvmBackendUtil.createMethod(functionalParameter);
if (!hasMethod) {
// A functional parameter that's not method wrapped will already be Callable-wrapped
return false;
}
// Optimization: If we're in a scope where the Callable field is visible
// we don't need to create a method ref
Scope scope = expr.getScope();
while (true) {
if (scope instanceof Package) {
break;
}
if (scope.equals(functionalParameter.getContainer())) {
return false;
}
scope = scope.getContainer();
}
// Otherwise we do require an AbstractCallable.
return true;
}
use of org.eclipse.ceylon.model.typechecker.model.Package in project ceylon by eclipse.
the class ExpressionTransformer method addThisOrObjectQualifierIfRequired.
/**
* We may need to force a qualified this prefix (direct or outer) in the following cases:
*
* - Required because of mixin inheritance with different type arguments (the same is already
* done for qualified references, but not for direct references)
* - The compiler generates anonymous local classes for things like
* Callables and Comprehensions. When referring to a member foo
* within one of those things we need a qualified {@code this}
* to ensure we're accessing the outer instances member, not
* a member of the anonymous local class that happens to have the same name.
*/
private JCExpression addThisOrObjectQualifierIfRequired(JCExpression qualExpr, Tree.StaticMemberOrTypeExpression expr, Declaration decl) {
// find out the real target
Declaration typeDecl;
if (Decl.isConstructor(decl))
typeDecl = ModelUtil.getConstructedClass(decl);
else
typeDecl = decl;
if (qualExpr == null && // statics are not members that can be inherited
!decl.isStatic() && (!Decl.isConstructor(decl) || !Decl.isConstructor(typeDecl)) && typeDecl.isMember() && // and have a name mapping)
expr.getTarget().getDeclaration() == decl && !ModelUtil.isLocalToInitializer(typeDecl) && !isWithinSuperInvocation()) {
// First check whether the expression is captured from an enclosing scope
TypeDeclaration outer = Decl.getOuterScopeOfMemberInvocation(expr, typeDecl);
if (outer != null) {
Type targetType = expr.getTarget().getQualifyingType();
Type declarationContainerType = ((TypeDeclaration) outer).getType();
// check if we need a variance cast
VarianceCastResult varianceCastResult = getVarianceCastResult(targetType, declarationContainerType);
// if we are within a comprehension body, or if we need a variance cast
if (isWithinSyntheticClassBody() || varianceCastResult != null) {
if (decl.isShared() && outer instanceof Interface) {
// always prefer qualified
qualExpr = makeQualifiedDollarThis(declarationContainerType);
} else {
// Class or companion class,
qualExpr = naming.makeQualifiedThis(makeJavaType(((TypeDeclaration) outer).getType(), JT_RAW | (outer instanceof Interface ? JT_COMPANION : 0)));
}
// add the variance cast if required
if (varianceCastResult != null) {
qualExpr = applyVarianceCasts(qualExpr, targetType, varianceCastResult, 0);
}
}
} else if (typeDecl.isClassOrInterfaceMember()) {
ClassOrInterface container;
if (((ClassOrInterface) typeDecl.getContainer()).isAnonymous() && ((ClassOrInterface) typeDecl.getContainer()).isToplevel()) {
// easy
container = (Class) typeDecl.getContainer();
} else {
// find the import
Import foundImport = statementGen().findImport(expr, decl);
container = (Class) foundImport.getTypeDeclaration();
}
Value value = (Value) ((Package) container.getContainer()).getMember(container.getName(), null, false);
qualExpr = make().Apply(null, naming.makeName(value, Naming.NA_FQ | Naming.NA_WRAPPER | Naming.NA_MEMBER), List.<JCExpression>nil());
} else if (decl.isMember() && !expr.getStaticMethodReference()) {
throw new BugException(expr, decl.getQualifiedNameString() + " was unexpectedly a member");
}
}
return qualExpr;
}
use of org.eclipse.ceylon.model.typechecker.model.Package in project ceylon by eclipse.
the class ExpressionTransformer method transformConstructorDelegation.
/**
* Transform a delegated constructor call ({@code extends XXX()})
* which may be either a superclass initializer/constructor or a
* same-class constructor.
* @param extendedType
* @param delegation The kind of delegation
* @param invocation
* @param classBuilder
* @return
*/
JCStatement transformConstructorDelegation(Node extendedType, CtorDelegation delegation, Tree.InvocationExpression invocation, ClassDefinitionBuilder classBuilder, boolean forDelegationConstructor) {
if (delegation != null && delegation.isError()) {
return delegation.makeThrow(this);
}
Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) invocation.getPrimary()).getDeclaration();
java.util.List<ParameterList> paramLists = ((Functional) primaryDeclaration).getParameterLists();
if (paramLists.isEmpty()) {
classBuilder.getInitBuilder().delegateCall(at(extendedType).Exec(makeErroneous(extendedType, "compiler bug: super class " + primaryDeclaration.getName() + " is missing parameter list")));
return null;
}
SuperInvocation builder = new SuperInvocation(this, classBuilder.getForDefinition(), delegation, invocation, paramLists.get(0), forDelegationConstructor);
CallBuilder callBuilder = CallBuilder.instance(this);
boolean prevFnCall = withinInvocation(true);
try {
if (invocation.getPrimary() instanceof Tree.StaticMemberOrTypeExpression) {
transformTypeArguments(callBuilder, (Tree.StaticMemberOrTypeExpression) invocation.getPrimary());
}
at(builder.getNode());
JCExpression expr = null;
Scope outerDeclaration;
if (Decl.isConstructor(primaryDeclaration)) {
outerDeclaration = builder.getPrimaryDeclaration().getContainer().getContainer();
} else {
outerDeclaration = builder.getPrimaryDeclaration().getContainer();
}
if ((Strategy.generateInstantiator(builder.getPrimaryDeclaration()) || builder.getPrimaryDeclaration() instanceof Class) && outerDeclaration instanceof Interface && !((Interface) outerDeclaration).isJava()) {
// If the subclass is inner to an interface then it will be
// generated inner to the companion and we need to qualify the
// super(), *unless* the subclass is nested within the same
// interface as it's superclass.
Scope outer = builder.getSub().getContainer();
while (!(outer instanceof Package)) {
if (outer == outerDeclaration) {
expr = naming.makeSuper();
break;
}
outer = outer.getContainer();
}
if (expr == null) {
if (delegation.isSelfDelegation()) {
throw new BugException();
}
Interface iface = (Interface) outerDeclaration;
JCExpression superQual;
if (ModelUtil.getClassOrInterfaceContainer(classBuilder.getForDefinition(), false) instanceof Interface) {
superQual = naming.makeCompanionAccessorCall(naming.makeQuotedThis(), iface);
} else {
superQual = naming.makeCompanionFieldName(iface);
}
expr = naming.makeQualifiedSuper(superQual);
}
} else {
expr = delegation.isSelfDelegation() ? naming.makeThis() : naming.makeSuper();
}
final List<JCExpression> superArguments = transformSuperInvocationArguments(classBuilder, builder, callBuilder);
JCExpression superExpr = callBuilder.invoke(expr).arguments(superArguments).build();
return at(extendedType).Exec(superExpr);
// classBuilder.getInitBuilder().superCall(at(extendedType).Exec(superExpr));
} finally {
withinInvocation(prevFnCall);
}
}
use of org.eclipse.ceylon.model.typechecker.model.Package in project ceylon by eclipse.
the class CeylonClassWriter method writeClass.
@Override
public JavaFileObject writeClass(ClassSymbol c) throws IOException, PoolOverflow, StringOverflow {
String packageName = c.packge().getQualifiedName().toString();
Package pkg = modelLoader.findPackage(packageName);
if (pkg == null)
throw new RuntimeException("Failed to find package: " + packageName);
Module module = pkg.getModule();
fileManager.setModule(module);
return super.writeClass(c);
}
use of org.eclipse.ceylon.model.typechecker.model.Package in project ceylon by eclipse.
the class MethodDefinitionBuilder method isParamTypeLocalToMethod.
private boolean isParamTypeLocalToMethod(Parameter parameter, Type nonWideningType) {
// error recovery
if (nonWideningType == null)
return false;
if (parameter.getModel().getTypeErased()) {
return false;
}
// make sure we resolve aliases
nonWideningType = nonWideningType.resolveAliases();
Declaration method = parameter.getDeclaration();
TypeDeclaration paramTypeDecl = nonWideningType.getDeclaration();
if (paramTypeDecl instanceof TypeParameter && Decl.equalScopeDecl(paramTypeDecl.getContainer(), method)) {
return false;
}
Scope scope = paramTypeDecl.getContainer();
while (scope != null && !(scope instanceof Package)) {
if (Decl.equalScopeDecl(scope, method)) {
return true;
}
scope = scope.getContainer();
}
return false;
}
Aggregations