Skip to content

SIP-19 on Implicit Source Locations #70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 30, 2012
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions sips/pending/_posts/2012-03-30-source-locations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
layout: sip
disqus: true
title: SIP-19 Implicit Source Locations
---

**Philipp Haller**

**30 March 2012**

## Motivation ##

The Scala compiler's error messages would be nearly useless if they wouldn't provide the corresponding source location, that is, file name, line number, and (some representation of the) character offset, of each error. However, source locations are also very useful outside of the compiler. Libraries and frameworks routinely deal with application- or system-level errors (usually in the form of exceptions), logging, debugging support through tracing, etc. All of these aspects greatly benefit from source location information.

Moreover, embedded domain-specific languages often depend upon source location information for providing useful error messages. Domain-specific languages that employ staging for code generation can use source locations for debug information in the generated code.

This proposal discusses a minimal extension of Scala's implicit parameters to provide access to the source location of method invocations. The design is analogous to the way manifests are generated by the compiler, and should therefore be natural to anyone familiar with manifests in Scala.

## Example ##

To obtain the source location for each invocation of a method `debug`, say, one adds an implicit parameter of type `SourceLocation`:

def debug(message: String)(implicit loc: SourceLocation): Unit = {
println("@" + loc.fileName + ":" + loc.line + ": " + message)
}

This means that inside the body of the `debug` method, we can access the source location of its current invocation through the `loc` parameter. For example, suppose
we are invoking `debug` on line `34` in a file `"MyApp.scala"`:

34: if (debugEnabled) debug("debug message")

Assuming `debugEnabled` evaluates to `true`, the above expression would lead to the following output:

@MyApp.scala:34: debug message

## The SourceLocation Trait ##

The `SourceLocation` trait is a new type member of the `scala.reflect` package. It has the following members:

trait SourceLocation {
/** The name of the source file */
def fileName: String

/** The line number */
def line: Int

/** The character offset */
def charOffset: Int
}

## Specification ##

Implicit source locations are supported through the following small addition to Scala's implicit rules.

If an implicit parameter of a method or constructor is of type `SourceLocation`, a source location object is determined according to the following rules.

First, if there is already an implicit argument of type `SourceLocation`, this argument is selected. Otherwise, an instance of `SourceLocation` is generated by invoking the `apply` method of the object `scala.reflect.SourceLocation`, passing the components of the source location as arguments.

## Implementation ##

An implementation of this proposal can be found at:

https://github.com/phaller/scala/tree/topic/source-location

An extension of this proposal is also part of Scala-Virtualized. The extension adds a subtrait `SourceContext` which in addition provides access to information, such as variable names in the context of a method invocation. More information can be found at:

https://github.com/TiarkRompf/scala-virtualized/wiki/SourceLocation-and-SourceContext