use of com.redhat.ceylon.model.typechecker.model.Parameter in project ceylon-compiler by ceylon.
the class ClassOrPackageDoc method getParametersAssertions.
private Map<Parameter, Map<Tree.Assertion, List<Tree.Condition>>> getParametersAssertions(final Declaration decl) {
final Map<Parameter, Map<Tree.Assertion, List<Tree.Condition>>> parametersAssertions = new LinkedHashMap<Parameter, Map<Tree.Assertion, List<Tree.Condition>>>();
if (((Functional) decl).getParameterLists().isEmpty()) {
return parametersAssertions;
}
Node node = tool.getNode(decl);
PhasedUnit pu = tool.getUnit(decl);
if (node == null || pu == null) {
return parametersAssertions;
}
Tree.Body body = null;
if (node instanceof Tree.MethodDefinition) {
body = ((Tree.MethodDefinition) node).getBlock();
} else if (node instanceof Tree.ClassDefinition) {
body = ((Tree.ClassDefinition) node).getClassBody();
}
if (body == null) {
return parametersAssertions;
}
final Map<String, Parameter> parametersNames = new HashMap<String, Parameter>();
for (ParameterList parameterList : ((Functional) decl).getParameterLists()) {
for (Parameter parameter : parameterList.getParameters()) {
parametersNames.put(parameter.getName(), parameter);
}
}
body.visitChildren(new Visitor() {
private boolean stop = false;
private Tree.Assertion assertion = null;
private Set<Parameter> referencedParameters = new HashSet<Parameter>();
@Override
public void visit(Tree.Assertion that) {
assertion = that;
super.visit(that);
assertion = null;
}
@Override
public void visit(Tree.Condition that) {
referencedParameters.clear();
super.visit(that);
if (assertion != null && !referencedParameters.isEmpty()) {
for (Parameter referencedParameter : referencedParameters) {
Map<Tree.Assertion, List<Tree.Condition>> parameterAssertions = parametersAssertions.get(referencedParameter);
if (parameterAssertions == null) {
parameterAssertions = new LinkedHashMap<Tree.Assertion, List<Tree.Condition>>();
parametersAssertions.put(referencedParameter, parameterAssertions);
}
List<Tree.Condition> parameterConditions = parameterAssertions.get(assertion);
if (parameterConditions == null) {
parameterConditions = new ArrayList<Tree.Condition>();
parameterAssertions.put(assertion, parameterConditions);
}
parameterConditions.add(that);
}
}
}
@Override
public void visit(Tree.BaseMemberExpression that) {
if (assertion != null) {
Declaration d = that.getDeclaration();
Scope realScope = com.redhat.ceylon.model.typechecker.model.ModelUtil.getRealScope(d.getScope());
if (parametersNames.containsKey(d.getName()) && realScope == decl) {
referencedParameters.add(parametersNames.get(d.getName()));
}
}
super.visit(that);
}
@Override
public void visit(Tree.Statement that) {
if (assertion == null) {
stop = true;
}
super.visit(that);
}
@Override
public void visitAny(Node that) {
if (!stop) {
super.visitAny(that);
}
}
});
return parametersAssertions;
}
use of com.redhat.ceylon.model.typechecker.model.Parameter in project ceylon-compiler by ceylon.
the class ClassOrPackageDoc method writeParameters.
protected final void writeParameters(Declaration decl) throws IOException {
if (decl instanceof Functional) {
Map<Parameter, Map<Tree.Assertion, List<Tree.Condition>>> parametersAssertions = getParametersAssertions(decl);
boolean first = true;
List<ParameterList> parameterLists = ((Functional) decl).getParameterLists();
for (ParameterList parameterList : parameterLists) {
for (Parameter parameter : parameterList.getParameters()) {
ParameterDocData parameterDocData = getParameterDocData(parameter, parametersAssertions);
if (!parameterDocData.isEmpty()) {
if (first) {
first = false;
open("div class='parameters section'");
around("span class='title'", "Parameters: ");
open("ul");
}
open("li");
open("code");
around("span class='parameter' id='" + decl.getName() + "-" + parameter.getName() + "'", parameter.getName());
// if parameter is function, we need to produce links to its parameters
if (parameter.getModel() instanceof Function) {
writeParameterLinksIfRequired((Function) parameter.getModel(), false, decl.getName() + "-");
}
if (!isEmpty(parameterDocData.defaultValue)) {
around("span class='parameter-default-value' title='Parameter default value'", " = " + parameterDocData.defaultValue);
}
close("code");
if (!isEmpty(parameterDocData.doc)) {
around("div class='doc section'", parameterDocData.doc);
}
writeParameterAssertions(decl, parameterDocData.parameterAssertions);
close("li");
}
}
}
if (!first) {
close("ul");
close("div");
}
}
}
use of com.redhat.ceylon.model.typechecker.model.Parameter in project ceylon-compiler by ceylon.
the class CallableBuilder method methodReference.
/**
* Constructs an {@code AbstractCallable} suitable for wrapping a
* method reference. For example:
* <pre>
* void someMethod() { ... }
* Anything() ref = someMethod;
* </pre>
*/
public static JCExpression methodReference(CeylonTransformer gen, final Tree.StaticMemberOrTypeExpression forwardCallTo, ParameterList parameterList) {
ListBuffer<JCStatement> letStmts = ListBuffer.<JCTree.JCStatement>lb();
CallableBuilder cb = new CallableBuilder(gen, forwardCallTo, forwardCallTo.getTypeModel(), parameterList);
cb.parameterTypes = cb.getParameterTypesFromCallableModel();
Naming.SyntheticName instanceFieldName;
boolean instanceFieldIsBoxed = false;
if (forwardCallTo instanceof Tree.QualifiedMemberOrTypeExpression && !ExpressionTransformer.isSuperOrSuperOf(((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getPrimary()) && !ExpressionTransformer.isPackageQualified((Tree.QualifiedMemberOrTypeExpression) forwardCallTo)) {
if ((((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getMemberOperator() instanceof Tree.SpreadOp)) {
instanceFieldIsBoxed = true;
instanceFieldName = null;
} else {
Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) forwardCallTo;
boolean prevCallableInv = gen.expressionGen().withinSyntheticClassBody(true);
try {
instanceFieldName = gen.naming.synthetic(Unfix.$instance$);
int varTypeFlags = Decl.isPrivateAccessRequiringCompanion(qmte) ? JT_COMPANION : 0;
Type primaryType;
if (Decl.isValueTypeDecl(qmte.getPrimary().getTypeModel())) {
primaryType = qmte.getPrimary().getTypeModel();
} else {
primaryType = qmte.getTarget().getQualifyingType();
}
if (((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getMemberOperator() instanceof Tree.SafeMemberOp) {
primaryType = gen.typeFact().getOptionalType(primaryType);
}
JCExpression primaryExpr = gen.expressionGen().transformQualifiedMemberPrimary(qmte);
if (Decl.isPrivateAccessRequiringCompanion(qmte)) {
primaryExpr = gen.naming.makeCompanionAccessorCall(primaryExpr, (Interface) qmte.getDeclaration().getContainer());
}
Type varType = qmte.getDeclaration().isShared() ? primaryType : Decl.getPrivateAccessType(qmte);
if (qmte.getPrimary().getUnboxed() == false) {
varTypeFlags |= JT_NO_PRIMITIVES;
instanceFieldIsBoxed = true;
}
letStmts.add(gen.makeVar(Flags.FINAL, instanceFieldName, gen.makeJavaType(varType, varTypeFlags), primaryExpr));
if (qmte.getPrimary() instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) qmte.getPrimary()).getDeclaration() instanceof TypedDeclaration) {
cb.instanceSubstitution = gen.naming.addVariableSubst((TypedDeclaration) ((Tree.MemberOrTypeExpression) qmte.getPrimary()).getDeclaration(), instanceFieldName.getName());
}
} finally {
gen.expressionGen().withinSyntheticClassBody(prevCallableInv);
}
}
} else {
instanceFieldName = null;
}
CallableTransformation tx;
cb.defaultValueCall = new DefaultValueMethodTransformation() {
@Override
public JCExpression makeDefaultValueMethod(AbstractTransformer gen, Parameter defaultedParam, List<JCExpression> defaultMethodArgs) {
JCExpression fn = null;
if (forwardCallTo instanceof Tree.BaseMemberOrTypeExpression) {
fn = gen.naming.makeDefaultedParamMethod(null, defaultedParam);
} else if (forwardCallTo instanceof Tree.QualifiedMemberOrTypeExpression) {
JCExpression qualifier = gen.expressionGen().transformTermForInvocation(((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getPrimary(), null);
fn = gen.naming.makeDefaultedParamMethod(qualifier, defaultedParam);
}
return gen.make().Apply(null, fn, defaultMethodArgs);
}
};
if (cb.isVariadic) {
tx = cb.new VariadicCallableTransformation(cb.new CallMethodWithForwardedBody(instanceFieldName, instanceFieldIsBoxed, forwardCallTo, false));
} else {
tx = cb.new FixedArityCallableTransformation(cb.new CallMethodWithForwardedBody(instanceFieldName, instanceFieldIsBoxed, forwardCallTo, true), null);
}
cb.useTransformation(tx);
return letStmts.isEmpty() ? cb.build() : gen.make().LetExpr(letStmts.toList(), cb.build());
}
use of com.redhat.ceylon.model.typechecker.model.Parameter in project ceylon-compiler by ceylon.
the class CallableBuilder method unboundValueMemberReference.
/**
* Used for "static" value references. For example:
* <pre>
* value x = Integer.plus;
* value y = Foo.method;
* value z = Outer.Inner;
* </pre>
*/
public static CallableBuilder unboundValueMemberReference(CeylonTransformer gen, Tree.QualifiedMemberOrTypeExpression qmte, Type typeModel, final TypedDeclaration value) {
CallBuilder callBuilder = CallBuilder.instance(gen);
Type qualifyingType = qmte.getTarget().getQualifyingType();
JCExpression target = gen.naming.makeUnquotedIdent(Unfix.$instance$);
target = gen.expressionGen().applyErasureAndBoxing(target, qmte.getPrimary().getTypeModel(), true, BoxingStrategy.BOXED, qualifyingType);
if (gen.expressionGen().isThrowableMessage(qmte)) {
callBuilder.invoke(gen.utilInvocation().throwableMessage());
callBuilder.argument(target);
} else if (gen.expressionGen().isThrowableSuppressed(qmte)) {
callBuilder.invoke(gen.utilInvocation().suppressedExceptions());
callBuilder.argument(target);
} else {
JCExpression memberName = gen.naming.makeQualifiedName(target, value, Naming.NA_GETTER | Naming.NA_MEMBER);
if (value instanceof FieldValue) {
callBuilder.fieldRead(memberName);
} else {
callBuilder.invoke(memberName);
}
}
JCExpression innerInvocation = callBuilder.build();
// use the return type since the value is actually applied
Type returnType = gen.getReturnTypeOfCallable(typeModel);
innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, returnType, // expression is a Callable
qmte.getTypeErased(), !CodegenUtil.isUnBoxed(value), BoxingStrategy.BOXED, returnType, 0);
ParameterList outerPl = new ParameterList();
Parameter instanceParameter = new Parameter();
instanceParameter.setName(Naming.name(Unfix.$instance$));
Value valueModel = new Value();
instanceParameter.setModel(valueModel);
Type accessType = gen.getParameterTypeOfCallable(typeModel, 0);
;
if (!value.isShared()) {
accessType = Decl.getPrivateAccessType(qmte);
}
valueModel.setName(instanceParameter.getName());
valueModel.setInitializerParameter(instanceParameter);
valueModel.setType(accessType);
valueModel.setUnboxed(false);
outerPl.getParameters().add(instanceParameter);
CallableBuilder outer = new CallableBuilder(gen, null, typeModel, outerPl);
outer.parameterTypes = outer.getParameterTypesFromParameterModels();
List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
outer.useDefaultTransformation(innerBody);
outer.companionAccess = Decl.isPrivateAccessRequiringCompanion(qmte);
return outer;
}
use of com.redhat.ceylon.model.typechecker.model.Parameter in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformArgumentsForCallableSpecifier.
private List<ExpressionAndType> transformArgumentsForCallableSpecifier(CallableSpecifierInvocation invocation) {
List<ExpressionAndType> result = List.<ExpressionAndType>nil();
int argIndex = 0;
for (Parameter parameter : invocation.getMethod().getFirstParameterList().getParameters()) {
Type exprType = expressionGen().getTypeForParameter(parameter, null, this.TP_TO_BOUND);
Parameter declaredParameter = invocation.getMethod().getFirstParameterList().getParameters().get(argIndex);
JCExpression arg = naming.makeName(parameter.getModel(), Naming.NA_IDENT);
arg = expressionGen().applyErasureAndBoxing(arg, exprType, !parameter.getModel().getUnboxed(), // Callables always have boxed params
BoxingStrategy.BOXED, declaredParameter.getType());
result = result.append(new ExpressionAndType(arg, makeJavaType(declaredParameter.getType())));
argIndex++;
}
return result;
}
Aggregations