Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Commit

Permalink
allow 'value' modifier for inferred parameters #4497
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinking committed Apr 15, 2017
1 parent 4d6c902 commit 80ee26f
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ else if (unit.isEmptyType(et)) {
if (type instanceof Tree.LocalModifier &&
!isNativeForWrongBackend(
dec.getScopedBackends())) {
if (dec.isParameter()) {
if (dec.isParameter() && !dec.isInferred()) {
type.addError(
"parameter may not have inferred type: '" +
dec.getName() +
Expand Down Expand Up @@ -3522,15 +3522,11 @@ private void inferParameterTypesFromCallableType(
j<aps.size();
j++) {
Tree.Parameter ap = aps.get(j);
if (ap instanceof Tree.InitializerParameter) {
Parameter parameter =
ap.getParameterModel();
if (parameter.getModel()==null) {
createInferredParameter(anon,
declaration, ap,
parameter,
types.get(j));
}
if (isInferrableParameter(ap)) {
createInferredParameter(anon,
declaration, ap,
ap.getParameterModel(),
types.get(j));
}
}
}
Expand All @@ -3556,20 +3552,31 @@ private void inferParameterTypesFromCallableParameter(
j++) {
Parameter fp = fps.get(j);
Tree.Parameter ap = aps.get(j);
if (ap instanceof Tree.InitializerParameter) {
Parameter parameter =
ap.getParameterModel();
if (parameter.getModel()==null) {
createInferredParameter(anon,
declaration, ap,
parameter,
pr.getTypedParameter(fp)
.getType());
}
if (isInferrableParameter(ap)) {
createInferredParameter(anon,
declaration, ap,
ap.getParameterModel(),
pr.getTypedParameter(fp)
.getType());
}
}
}
}

private static boolean isInferrableParameter(Tree.Parameter p) {
if (p instanceof Tree.ValueParameterDeclaration) {
Tree.ValueParameterDeclaration vpd =
(Tree.ValueParameterDeclaration) p;
return vpd.getTypedDeclaration().getType()
instanceof Tree.ValueModifier;
}
else if (p instanceof Tree.InitializerParameter) {
return p.getParameterModel().getModel() == null;
}
else {
return false;
}
}

/**
* Create a model for an inferred parameter of an
Expand All @@ -3581,23 +3588,31 @@ private void createInferredParameter(Tree.FunctionArgument anon,
if (isTypeUnknown(type)) {
type = unit.getUnknownType();
if (!dynamic) {
ap.addError("could not infer parameter type: '" +
parameter.getName() +
"' would have unknown type");
ap.addError("could not infer parameter type: '"
+ parameter.getName()
+ "' would have unknown type");
}
}
else if (involvesTypeParams(declaration, type)) {
ap.addError("could not infer parameter type: '" +
parameter.getName() +
"' would have type '" +
type.asString(unit) +
"' involving type parameters");
ap.addError("could not infer parameter type: '"
+ parameter.getName()
+ "' would have type '"
+ type.asString(unit)
+ "' involving type parameters");
type = unit.getUnknownType();
}
Value model = new Value();
model.setUnit(unit);
Value model = (Value) parameter.getModel();
if (model==null) {
model = new Value();
model.setUnit(unit);
model.setName(parameter.getName());
parameter.setModel(model);
Function m = anon.getDeclarationModel();
model.setContainer(m);
model.setScope(m);
m.addMember(model);
}
model.setType(type);
model.setName(parameter.getName());
model.setInferred(true);
if (declaration!=null && type!=null
&& declaration.isJava()
Expand All @@ -3606,12 +3621,14 @@ else if (involvesTypeParams(declaration, type)) {
&& canHaveUncheckedNulls(type)) {
model.setUncheckedNullType(true);
}
parameter.setModel(model);
model.setInitializerParameter(parameter);
Function m = anon.getDeclarationModel();
model.setContainer(m);
model.setScope(m);
m.addMember(model);
if (ap instanceof Tree.ValueParameterDeclaration) {
Tree.ValueParameterDeclaration vpd =
(Tree.ValueParameterDeclaration) ap;
vpd.getTypedDeclaration()
.getType()
.setTypeModel(type);
}
}

private void visitInvocationPositionalArgs(
Expand Down
9 changes: 9 additions & 0 deletions typechecker/test/main/function/parameterInference.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ void parameterInference() {
=> if (exists fun) then fun("hello") else "";
print(hello((str) => str + "world"));
print(hello(null));

@type:"Iterable<Character,Null>" value mapped_ = "hello world".map((value c) => c.uppercased);
@type:"Iterable<Character,Null>" value filtered_ = "hello world".filter((value c) { return !c.whitespace; });
@type:"Integer" value folded_ = (1..10).fold(0)((value r, value x) => r+x);
accept((value f)=>f.string);
variadic((value string)=>print(string), (value string)=>print(string));

@error value funWithNoParamType = (p) => 0;
value funWithNoParamType_ = (@error value p) => 0;
}

void testNotVariable() {
Expand Down

0 comments on commit 80ee26f

Please sign in to comment.