Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Now completing simple class constructors.

  • Loading branch information...
commit fa1fe23499187decb114efb426ffe2582778bc2b 1 parent e9582e2
@aemoncannon aemoncannon authored
View
109 etc/gsoc_plan.textile
@@ -0,0 +1,109 @@
+h2. ENSIME Summer Development Plan
+
+This is the project plan for ENSIME during GSOC 2010. The plan lists high-level goals. Each goal entry must include an implementation note that addresses feasibility. We also include a priority annotion in the MoSCoW system:
+M Must have.
+S Should have.
+C Could have if it doesn't affect other priorities.
+W Won't have, but would like for the future.
+
+_Rough_ time estimates are included.
+
+As ENSIME is already a functional project (barely), some of the goals below make reference to improving or completing existing features. As of May 17, 2010, none of the goals below has been completed.
+
+
+
+h3. Extract project information (dependencies and source locations) from existing build scripts.
+** Overall goal is that ENSIME works 'out of the box' for as many users as possible.
+** Handle at least Maven, Ivy and SBT projects. SBT already handles all these.
+** Possibly link to SBT libraries for this task.
+** Time Estimate: 1 week
+** Priority: M
+
+h3. Improvements to Entity Browser
+** Show class constructors
+** Annotate with 'implicit' for interfaces that are acquired implicitely.
+** Keyboard shortcuts for jumping to source or docs in Package Brwoser
+** Link type parameters separately
+** Time Estimate: 3-4 days
+** Priority: C
+
+h3. Fix scaladoc linking to jump to specific method in Scala html docs.
+** Priority: W
+
+h3. Improvements to Auto-Completion
+** Completion of type names and type constructors.
+** Display type signatures in a less crowded way
+** Time Estimate: 2 days
+** Priority: C
+
+h3. Show implicit parameters for methods in Auto-Completion results
+** Priority: C
+
+h3. Incremental Building
+** Probably use nsc.interactive.BuildManager
+** Depends on completion of #1
+** Duplicates some SBT behaviour, but many folks don't use SBT
+** Time Estimate: 1.5 weeks
+** Priority: M
+
+h3. 'Problems' buffer and navigation
+** List all compilation errors and warnings, hyperlinked to source
+** This is separate from the problem highlighting which is already working
+** Time Estimate: 2 days
+** Priority: M
+
+h3. Provide commands for jumping to next or prev problem
+** Priority: C
+
+h3. Embedded Scala REPL
+** Depends on completion of #1
+** Use exiting code for running Scala REPL as inferior process
+** Time Estimate: 2 days
+** Priority: M
+
+h3. SBT integration
+** Code already exists for running SBT as an Emacs inferior process
+** ENSIME should be able to Automatically start inferior SBT
+** Provide key shortcuts for issuing SBT commands
+** Time Estimate: 2 days
+** Priority: M
+
+h3. Debugging
+** Investigate improvement of Emacs GUD mode with respect to Scala
+** Challenge will be translation of source names and positions to underlying java classes
+** Scala debugging should work as well as Java debugging (in Emacs)
+** Time Estimate: 2 weeks
+** Priority: M
+
+h3. 'Uses' search
+** List all uses of a particular method or type, hyperlinked to source
+** Depends on some unknowns in the compiler source..(can we do a global symbol search?)
+** Time Estimate: 1 week
+** Priority: S
+
+h3. A framework for automated refactorings.
+** Should support a basic set of refactorings. At least Rename and Organize Imports.
+** Should provide a clear path for adding new refactorings in the future.
+** Should provide reassuring user interface for selecting, confirming and reverting these operations.
+** Mirko Stocker is working on stand-alone refactorings. ENSIME work should be mostly GUI glue.
+** Time Estimate: 1.5 weeks
+** Priority: S+
+
+h3. Stability
+** Address issue in compiler back-end where type tree is sometimes not returned
+** Should make every effort to return a reasonable answer to user
+** Possibly cache last good tree
+** Time Estimate: 1 week
+** Priority: S
+
+h3. Documentation
+** Improve the installation, startup guide.
+** Describe all user configuration options
+** Document all Scala and Elisp code and generate API docs for Scala
+** Time Estimate: 4 days
+** Priority: M
+
+
+
+
+
View
36 src/main/elisp/auto-complete-ensime.el
@@ -1,17 +1,17 @@
(require 'auto-complete)
-(defun ac-ensime-move-point-back-to-call-target (prefix)
+(defun ensime-ac-move-point-back-to-call-target (prefix)
"Assuming the point is in a member prefix, move the point back so it's
at the last char of the call target.
"
(backward-char (length prefix))
(re-search-backward "[^\\. ]" (point-at-bol) t))
-(defun ac-ensime-member-candidates (prefix)
+(defun ensime-ac-member-candidates (prefix)
"Return candidate list."
(ensime-save-buffer-no-hook)
(save-excursion
- (ac-ensime-move-point-back-to-call-target prefix)
+ (ensime-ac-move-point-back-to-call-target prefix)
(let ((members (ensime-rpc-members-for-type-at-point prefix)))
(mapcar (lambda (m)
(let* ((type-name (plist-get m :type-name))
@@ -28,7 +28,7 @@
))
) members))))
-(defun ac-ensime-name-candidates (prefix)
+(defun ensime-ac-name-candidates (prefix)
"Return candidate list."
(ensime-save-buffer-no-hook)
(let ((names (ensime-rpc-name-completions-at-point prefix)))
@@ -48,17 +48,17 @@
) names)))
-(defun ac-ensime-get-doc (item)
+(defun ensime-ac-get-doc (item)
"Return doc for given item."
(get-text-property 0 'scala-type-name item))
-(defun ac-ensime-member-prefix ()
+(defun ensime-ac-member-prefix ()
"Starting at current point. Find the point of completion for a member access.
Return nil if we are not currently looking at a member access."
(let ((point (re-search-backward "[\\. ]+\\([^\\. ]*\\)?" (point-at-bol) t)))
(if point (1+ point))))
-(defun ac-ensime-name-prefix ()
+(defun ensime-ac-name-prefix ()
"Starting at current point. Find the point of completion for a symbol.
Return nil if we are not currently looking at a symbol."
(let ((pt-at-end-of-prev-line
@@ -69,7 +69,7 @@
point
))))
-(defun ac-ensime-complete-action ()
+(defun ensime-ac-complete-action ()
"Defines action to perform when user selects a completion candidate.
In this case, if the candidate is a method name, fill in place-holder
arguments."
@@ -163,26 +163,26 @@
(ac-define-source ensime-members
- '((document . ac-ensime-get-doc)
- (candidates . (ac-ensime-member-candidates ac-prefix))
- (prefix . ac-ensime-member-prefix)
- (action . ac-ensime-complete-action)
+ '((document . ensime-ac-get-doc)
+ (candidates . (ensime-ac-member-candidates ac-prefix))
+ (prefix . ensime-ac-member-prefix)
+ (action . ensime-ac-complete-action)
(requires . 0)
(symbol . "f")
(cache . t)
))
(ac-define-source ensime-scope-names
- '((document . ac-ensime-get-doc)
- (candidates . (ac-ensime-name-candidates ac-prefix))
- (prefix . ac-ensime-name-prefix)
- (action . ac-ensime-complete-action)
+ '((document . ensime-ac-get-doc)
+ (candidates . (ensime-ac-name-candidates ac-prefix))
+ (prefix . ensime-ac-name-prefix)
+ (action . ensime-ac-complete-action)
(requires . 0)
(symbol . "s")
(cache . t)
))
-(defun ac-ensime-enable ()
+(defun ensime-ac-enable ()
(make-local-variable 'ac-sources)
(setq ac-sources '(ac-source-ensime-scope-names
ac-source-ensime-members ))
@@ -199,7 +199,7 @@
(auto-complete-mode 1)
)
-(defun ac-ensime-disable ()
+(defun ensime-ac-disable ()
(auto-complete-mode 0)
)
View
11 src/main/elisp/ensime.el
@@ -161,7 +161,7 @@
(if ensime-mode
(progn
- (ac-ensime-enable)
+ (ensime-ac-enable)
(add-hook 'after-save-hook 'ensime-after-save-hook nil t)
(when ensime-tooltip-hints
(add-hook 'tooltip-functions 'ensime-tooltip-handler)
@@ -179,7 +179,7 @@
(define-key ensime-mode-map [C-mouse-1] 'ensime-control-mouse-1-single-click))
(progn
- (ac-ensime-disable)
+ (ensime-ac-disable)
(remove-hook 'after-save-hook 'ensime-after-save-hook t)
(remove-hook 'tooltip-functions 'ensime-tooltip-handler)
(make-local-variable 'track-mouse)
@@ -1206,7 +1206,6 @@ This doesn't mean it will connect right after Ensime is loaded."
"Make a connection out of PROCESS."
(let ((ensime-dispatching-connection process))
(ensime-init-connection-state config process)
- (ensime-select-connection process)
process))
(defmacro* ensime-with-connection-buffer ((&optional process) &rest body)
@@ -2388,7 +2387,6 @@ The buffer also uses the minor-mode `ensime-popup-buffer-mode'."
(set (make-local-variable 'truncate-lines) t)))
(ensime-define-keys ensime-connection-list-mode-map
- ("d" 'ensime-connection-list-make-default)
("g" 'ensime-update-connection-list)
((kbd "C-k") 'ensime-quit-connection-at-point)
("R" 'ensime-restart-connection-at-point))
@@ -2414,11 +2412,6 @@ The buffer also uses the minor-mode `ensime-popup-buffer-mode'."
(let ((ensime-dispatching-connection connection))
(ensime-restart-inferior-lisp)))
-(defun ensime-connection-list-make-default ()
- "Make the connection at point the default connection."
- (interactive)
- (ensime-select-connection (ensime-connection-at-point))
- (ensime-update-connection-list))
(defvar ensime-connections-buffer-name "*ENSIME Connections*")
View
1  src/main/scala/com/ensime/server/Compiler.scala
@@ -122,7 +122,6 @@ class Compiler(project:Project, config:ProjectConfig) extends Actor{
project ! RPCResultEvent(syms, callId)
}
-
case TypeCompletionEvent(file:File, point:Int, prefix:String, callId:Int) =>
{
val f = global.getSourceFile(file.getAbsolutePath())
View
34 src/main/scala/com/ensime/server/PresentationCompiler.scala
@@ -15,6 +15,7 @@ import scala.tools.nsc.symtab.Types
class PresentationCompiler(settings:Settings, reporter:Reporter, parent:Actor, srcFiles:Iterable[String]) extends Global(settings,reporter) with ModelBuilders{
+ import Helpers._
/**
* Override so we send a notification to compiler actor when finished..
@@ -77,29 +78,6 @@ class PresentationCompiler(settings:Settings, reporter:Reporter, parent:Actor, s
members.values.toList
}
- def isArrowType(tpe:Type) ={
- tpe match{
- case _:MethodType => true
- case _:PolyType => true
- case _ => false
- }
- }
-
- def isNoParamArrowType(tpe:Type) ={
- tpe match{
- case t:MethodType => t.params.isEmpty
- case t:PolyType => t.params.isEmpty
- case t:Type => false
- }
- }
-
- def typeOrArrowTypeResult(tpe:Type) ={
- tpe match{
- case t:MethodType => t.resultType
- case t:PolyType => t.resultType
- case t:Type => t
- }
- }
private def getMembersForTypeAt(p:Position):List[Member] = {
getTypeAt(p) match{
@@ -238,7 +216,7 @@ class PresentationCompiler(settings:Settings, reporter:Reporter, parent:Actor, s
}
}
- def completeSymbolAt(p: Position, prefix:String):List[ScopeNameInfoLight] = {
+ def completeSymbolAt(p: Position, prefix:String):List[SymbolInfoLight] = {
val x = new Response[List[Member]]()
askScopeCompletion(p, x)
val names = x.get match{
@@ -249,12 +227,8 @@ class PresentationCompiler(settings:Settings, reporter:Reporter, parent:Actor, s
m match{
case ScopeMember(sym, tpe, true, viaImport) => {
if(sym.nameString.startsWith(prefix)){
- List(new ScopeNameInfoLight(
- sym.nameString,
- tpe.underlying.toString,
- cacheType(tpe),
- isArrowType(tpe)
- ))
+ val constructors = SymbolInfoLight.constructorsNamed(sym,tpe)
+ List(SymbolInfoLight(sym, tpe)) ++ constructors
}
else{
List()
View
2  src/main/scala/com/ensime/server/Project.scala
@@ -66,7 +66,7 @@ class Project extends Actor with SwankHandler{
catch{
case e: Exception =>
{
- System.err.println("Error at Project message loop: " + e + " :\n" + e.getStackTraceString)
+ println("Error at Project message loop: " + e + " :\n" + e.getStackTraceString)
}
}
View
94 src/main/scala/com/ensime/server/model/Model.scala
@@ -16,7 +16,7 @@ object SExpConversion{
if(pos.isDefined){
SExp(
key(":file"), pos.source.path,
- key(":offset"), pos.point + 1 // <- Emacs points start at 1
+ key(":offset"), pos.point + 1 // <- Emacs point starts at 1
)
}
else{
@@ -80,43 +80,49 @@ class NamedTypeInfo(
class SymbolInfo(
val name:String,
val declPos:Position,
- val tpe:TypeInfo) extends SExpable {
+ val tpe:TypeInfo,
+ val isCallable:Boolean) extends SExpable {
def toSExp():SExp = {
SExp(
key(":name"), name,
key(":type"), tpe,
- key(":decl-pos"), declPos
+ key(":decl-pos"), declPos,
+ key(":is-callable"), isCallable
)
}
-
}
-class NamedTypeMemberInfo(override val name:String, val tpe:TypeInfo, val pos:Position) extends EntityInfo(name, List()) with SExpable {
+class SymbolInfoLight(
+ val name:String,
+ val tpeName:String,
+ val tpeId:Int,
+ val isCallable:Boolean) extends SExpable {
+
def toSExp():SExp = {
SExp(
key(":name"), name,
- key(":type"), tpe.toSExp,
- key(":pos"), pos
+ key(":type-name"), tpeName,
+ key(":type-id"), tpeId,
+ key(":is-callable"), isCallable
)
}
}
-class NamedTypeMemberInfoLight(override val name:String, tpeName:String, tpeId:Int, isCallable:Boolean) extends EntityInfo(name, List()){
+class NamedTypeMemberInfo(override val name:String, val tpe:TypeInfo, val pos:Position) extends EntityInfo(name, List()) with SExpable {
def toSExp():SExp = {
SExp(
key(":name"), name,
- key(":type-name"), tpeName,
- key(":type-id"), tpeId,
- key(":is-callable"), isCallable
+ key(":type"), tpe.toSExp,
+ key(":pos"), pos
)
}
}
-class ScopeNameInfoLight(override val name:String, tpeName:String, tpeId:Int, isCallable:Boolean) extends EntityInfo(name, List()){
+class NamedTypeMemberInfoLight(override val name:String, tpeName:String, tpeId:Int, isCallable:Boolean) extends EntityInfo(name, List()){
def toSExp():SExp = {
SExp(
key(":name"), name,
@@ -128,6 +134,7 @@ class ScopeNameInfoLight(override val name:String, tpeName:String, tpeId:Int, is
}
+
class TypeInfo(
val name:String,
val id:Int,
@@ -219,6 +226,30 @@ trait ModelBuilders { self: Global =>
object Helpers{
+ def isArrowType(tpe:Type) ={
+ tpe match{
+ case _:MethodType => true
+ case _:PolyType => true
+ case _ => false
+ }
+ }
+
+ def isNoParamArrowType(tpe:Type) ={
+ tpe match{
+ case t:MethodType => t.params.isEmpty
+ case t:PolyType => t.params.isEmpty
+ case t:Type => false
+ }
+ }
+
+ def typeOrArrowTypeResult(tpe:Type) ={
+ tpe match{
+ case t:MethodType => t.resultType
+ case t:PolyType => t.resultType
+ case t:Type => t
+ }
+ }
+
def normalizeSym(aSym: Symbol): Symbol = aSym match {
case null | EmptyPackage | NoSymbol => normalizeSym(RootPackage)
case ScalaObjectClass | ObjectClass => normalizeSym(AnyRefClass)
@@ -393,11 +424,46 @@ trait ModelBuilders { self: Global =>
new SymbolInfo(
sym.name.toString,
sym.pos,
- TypeInfo(sym.tpe))
+ TypeInfo(sym.tpe),
+ Helpers.isArrowType(sym.tpe)
+ )
+ }
+
+ def nullInfo() = {
+ new SymbolInfo("NA", NoPosition, TypeInfo.nullInfo, false)
+ }
+
+ }
+
+ object SymbolInfoLight{
+
+ def constructorsNamed(sym:Symbol, tpe:Type):List[SymbolInfoLight] = {
+ if(sym.isClass){
+ tpe.members.flatMap{ member:Symbol =>
+ if(member.isClassConstructor){
+ Some(SymbolInfoLight(sym, member.tpe))
+ }
+ else{None}
+ }
+ }
+ else{
+ List()
+ }
+ }
+
+ def apply(sym:Symbol):SymbolInfoLight = SymbolInfoLight(sym, sym.tpe)
+
+ def apply(sym:Symbol, tpe:Type):SymbolInfoLight = {
+ new SymbolInfoLight(
+ sym.name.toString,
+ tpe.underlying.toString,
+ cacheType(tpe.underlying),
+ Helpers.isArrowType(tpe.underlying)
+ )
}
def nullInfo() = {
- new SymbolInfo("NA", NoPosition, TypeInfo.nullInfo)
+ new SymbolInfoLight("NA", "NA", -1, false)
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.