We are removing this syntax. To stage the move, first error with
Fix-Its to rewrite to the keyword-argument syntax. In a week or so,
we'll remove all of the code supporting the "separated" call syntax.
Swift SVN r15833
Continue parsing operators after 'as <type>' or 'is <type>', which allows cast chains like 'x as Derived! as Base' or '1 as UInt8 + x' without parens, finishing <rdar://problem/15640006>.
Swift SVN r15357
Factor an IdentityExpr base class out of ParenExpr, and migrate most of the logic to see through ParenExprs to see through IdentityExprs instead. Add DotSelfExpr as a new subclass of IdentityExpr, produced by parsing 'x.self'.
Swift SVN r14381
An arbitrary value of class metatype cannot be used to construct an
object, because there's no guarantee that a given subclass will
provide that initializer.
Swift SVN r14175
Implement several rules that determine when an identifier on a new
line is a continuation of a selector-style call on a previous line:
- In certain contexts, such as parentheses or square brackets, it's
always a continuation because one does not split statements in
those contexts;
- Otherwise, compare the leading whitespace on the line containing
the nearest enclosing statement or declaration to the leading
whitespace for the line containing the identifier.
The leading whitespace for a line is currently defined as all space
and tab characters from the start of the line up to the first
non-space, non-tab character. Leading whitespace is compared via a
string comparison, which eliminates any dependency on the width of a
tab. One can run into a few amusing cases where adjacent lines that
look indented (under some specific tab width) aren't actually indented
according to this rule because there are different mixes of tabs and
spaces in the two lines. See the bottom of call-suffix-indent.swift
for an example.
I had to adjust two test cases that had lines with slightly different
indentation. The diagnostics here are awful; I've made no attempt at
improving them.
Swift SVN r13843
This allows expressions such as ".foo" and ".foo(1)" to refer to
static variables and static methods, respectively, as well as enum
cases.
To get here, rework the parsing of delayed identifier expressions a
bit, so that the argument itself is part of the delayed argument
expression rather than a separate call expression. This simplifies
both the handling of patterns of this form and the type checker, which
can now user simpler constraints.
If we really want to support (.foo)(1), we can make that work, but it
seems unnecessary and perhaps confusing.
Swift SVN r10626
There's a lot more work to do here, but start to categorize tests
along the lines of what a specification might look like, with
directories (chapters) for basic concepts, declarations, expressions,
statements, etc.
Swift SVN r9958
This addresses the bulk of <rdar://problem/15344950>, which involes us
not being able to find local variable declarations in expressions when
the parser didn't pre-bind them for us.
The fix to name lookup itself insures that a case such as
case (var a, a)
doesn't allow the second 'a' to find the first.
Swift SVN r9858
An expression of DynamicLookup type can be unconditionally downcast to
any class type via the postfix '!'. This will allow one to replace
var w : NSWindow = (nsarray[0] as NSWindow)!
with
var w : NSWindow = nsarray[0]!
The current implementation is fairly limited: it only works when the
operand of '!' is an rvalue of type DynamicLookup, and we don't ensure
that the result is a class type. Nonetheless, it cleans up some of
ListMaker nicely.
This is the first client of disjunction constraints, which were added
in r9142.
Swift SVN r9151
In this syntax, the closure signature (when present) is placed within
the braces and the 'in' keyword separates it from the body of the
closure, e.g.,
magic(42, { (x : Int, y : Int) -> Bool in
print("Comparing \(x) to \(y).\n")
return y < x
})
When types are omitted from the parameter list, one can also drop the
parentheses, e.g.,
magic(42, { x, y -> Bool in
print("Comparing \(x) to \(y).\n")
return y < x
})
The parsing is inefficient and recovers poorly (in part because 'in'
is a contextual keyword rather than a real keyword), but it should
handle the full grammar. A number of tests, along with the whitepaper
and related rational documents, still need to be updated. Still, this
is the core of <rdar://problem/14004323>.
Swift SVN r6105
This moves trailing closures from expr-postfix up to the level of
expr, and introduces an intermediate level (expr-basic) for places
that need to parse expressions followed by curly braces, such as
if/while/switch/for. Trailing closures are still restricted to occur
after expr-postfix, although the parser itself parses a slightly more
general and then complains if it got more than an expr-postfix.
Swift SVN r5256
Trailing closure syntax allows one to write a closure following any
other postfix expression, which passes the closure to that postfix
expression as an arguments. For example:
sort(fruits) { |lhs, rhs|
print("Comparing \(lhs) to \(rhs)\n")
return lhs > rhs
}
As a temporary limitation to work around the ambiguity with
if foo { ... } { ... }
we require trailing closures to have an explicit parameter list, e.g.,
if foo { || ... } { ... }
Swift SVN r5210
'|' is part of the character set for operators, but within the
signature of a closure we need to treat the first non-nested '|' as
the closing delimiter for the closure parameter list. For example,
{ |x = 1| 2 + x}
parses with the default value of '1' for x, with the body 2 + x. If
the '|' operator is needed in the default value, it can be wrapped in
parentheses:
{ |x = (1|2)| x }
Note that we have problems with both name binding and type checking
for default values in closures (<rdar://problem/13372694>), so they
aren't actually enabled. However, this allows us to parse them and
recover better in their presence.
Swift SVN r5202
This commit implements closure syntax that places the (optional)
parameter list in pipes within the curly braces of a closure. This
syntax "slides" well from very simple closures with anonymous
arguments, e.g.,
sort(array, {$1 > $0})
to naming the arguments
sort(array, {|x, y| x > y})
to adding a return type and/or parameter types
sort(array, {|x : String, y : String| -> Bool x > y})
and with multiple statements in the body:
sort(array, {|x, y|
print("Comparing \(x) and \(y)\n")
return x > y
})
When the body contains only a single expression, that expression
participates in type inference with its enclosing expression, which
allows one to type-check, e.g.,
map(strings, {|x| x.toUpper()})
without context. If one has multiple statements, however, one will
need to provide additional type information either with context
strings = map(strings, {
return $0.toUpper()
})
or via annotations
map(strings, {|x| -> String
return x.toUpper()
}
because we don't perform inter-statement type inference.
The new closure expressions are only available with the new type
checker, where they completely displace the existing { $0 + $1 }
anonymous closures. 'func' expressions remain unchanged.
The tiny test changes (in SIL output and the constraint-checker test)
are due to the PipeClosureExpr AST storing anonymous closure arguments
($0, $1, etc.) within a pattern in the AST. It's far cleaner to
implement this way.
The testing here is still fairly light. In particular, we need better
testing of parser recovery, name lookup for closures with local types,
more deduction scenarios, and multi-statement closures (which don't
get exercised beyond the unit tests).
Swift SVN r5169
There is a special-case hack to allow capture of 'this', which is
implicitly [byref] for structs. At the moment, most of the cases where
this hack is necessary are [auto_closure] parameters (for assertions
and &&/||).
Swift SVN r5047