| 
									
										
										
										
											2008-10-24 14:08:01 -07:00
										 |  |  | // Copyright 2009 The Go Authors.  All rights reserved. | 
					
						
							|  |  |  | // Use of this source code is governed by a BSD-style | 
					
						
							|  |  |  | // license that can be found in the LICENSE file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package Compilation | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 15:19:34 -08:00
										 |  |  | import ( | 
					
						
							| 
									
										
										
										
											2009-04-16 20:52:37 -07:00
										 |  |  | 	"container/vector"; | 
					
						
							| 
									
										
										
										
											2009-02-06 11:10:25 -08:00
										 |  |  | 	"fmt"; | 
					
						
							| 
									
										
										
										
											2009-04-16 20:52:37 -07:00
										 |  |  | 	"go/ast"; | 
					
						
							|  |  |  | 	"go/parser"; | 
					
						
							|  |  |  | 	"go/scanner"; | 
					
						
							|  |  |  | 	"go/token"; | 
					
						
							| 
									
										
										
										
											2009-02-06 11:10:25 -08:00
										 |  |  | 	"os"; | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	"platform"; | 
					
						
							|  |  |  | 	"sort"; | 
					
						
							| 
									
										
										
										
											2009-04-16 20:52:37 -07:00
										 |  |  | 	"typechecker"; | 
					
						
							|  |  |  | 	"utf8"; | 
					
						
							|  |  |  | 	"utils"; | 
					
						
							| 
									
										
										
										
											2009-01-14 15:19:34 -08:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2008-10-24 14:08:01 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | func assert(b bool) { | 
					
						
							|  |  |  | 	if !b { | 
					
						
							|  |  |  | 		panic("assertion failed"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-24 14:08:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-20 14:40:40 -08:00
										 |  |  | type Flags struct { | 
					
						
							| 
									
										
										
										
											2009-01-16 15:31:34 -08:00
										 |  |  | 	Verbose bool; | 
					
						
							|  |  |  | 	Deps bool; | 
					
						
							|  |  |  | 	Columns bool; | 
					
						
							| 
									
										
										
										
											2008-10-24 14:08:01 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | type Error struct { | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | 	Pos token.Position; | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	Msg string; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type ErrorList []Error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (list ErrorList) Len() int { return len(list); } | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | func (list ErrorList) Less(i, j int) bool { return list[i].Pos.Offset < list[j].Pos.Offset; } | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | func (list ErrorList) Swap(i, j int) { list[i], list[j] = list[j], list[i]; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-15 17:16:41 -08:00
										 |  |  | type errorHandler struct { | 
					
						
							| 
									
										
										
										
											2008-11-24 18:24:21 -08:00
										 |  |  | 	filename string; | 
					
						
							|  |  |  | 	columns bool; | 
					
						
							| 
									
										
										
										
											2009-03-11 12:52:11 -07:00
										 |  |  | 	errline int; | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	errors vector.Vector; | 
					
						
							| 
									
										
										
										
											2008-11-24 18:24:21 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-31 13:28:01 -07:00
										 |  |  | func (h *errorHandler) Init(filename string, columns bool) { | 
					
						
							| 
									
										
										
										
											2008-11-24 18:24:21 -08:00
										 |  |  | 	h.filename = filename; | 
					
						
							|  |  |  | 	h.columns = columns; | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	h.errors.Init(0); | 
					
						
							| 
									
										
										
										
											2008-11-24 18:24:21 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | func (h *errorHandler) Error(pos token.Position, msg string) { | 
					
						
							| 
									
										
										
										
											2009-04-16 20:52:37 -07:00
										 |  |  | 	// only report errors that are on a new line | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	// in the hope to avoid most follow-up errors | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | 	if pos.Line == h.errline { | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2008-11-24 18:24:21 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-19 03:05:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	// report error | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | 	fmt.Printf("%s:%d:", h.filename, pos.Line); | 
					
						
							| 
									
										
										
										
											2009-03-11 12:52:11 -07:00
										 |  |  | 	if h.columns { | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | 		fmt.Printf("%d:", pos.Column); | 
					
						
							| 
									
										
										
										
											2008-11-24 18:24:21 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-03-11 12:52:11 -07:00
										 |  |  | 	fmt.Printf(" %s\n", msg); | 
					
						
							| 
									
										
										
										
											2008-12-19 03:05:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	// collect the error | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | 	h.errors.Push(Error{pos, msg}); | 
					
						
							|  |  |  | 	h.errline = pos.Line; | 
					
						
							| 
									
										
										
										
											2008-11-24 18:24:21 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-31 16:53:58 -07:00
										 |  |  | func Compile(filename string, flags *Flags) (*ast.Program, ErrorList) { | 
					
						
							| 
									
										
										
										
											2009-03-31 13:28:01 -07:00
										 |  |  | 	src, os_err := os.Open(filename, os.O_RDONLY, 0); | 
					
						
							|  |  |  | 	defer src.Close(); | 
					
						
							|  |  |  | 	if os_err != nil { | 
					
						
							|  |  |  | 		fmt.Printf("cannot open %s (%s)\n", filename, os_err.String()); | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 		return nil, nil; | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-12-19 03:05:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-15 17:16:41 -08:00
										 |  |  | 	var err errorHandler; | 
					
						
							| 
									
										
										
										
											2009-03-31 13:28:01 -07:00
										 |  |  | 	err.Init(filename, flags.Columns); | 
					
						
							| 
									
										
										
										
											2008-10-24 14:08:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-31 13:28:01 -07:00
										 |  |  | 	mode := parser.ParseComments; | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | 	if flags.Verbose { | 
					
						
							| 
									
										
										
										
											2009-03-27 19:27:09 -07:00
										 |  |  | 		mode |= parser.Trace; | 
					
						
							| 
									
										
										
										
											2009-03-26 16:10:07 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-03-31 13:28:01 -07:00
										 |  |  | 	prog, ok2 := parser.Parse(src, &err, mode); | 
					
						
							| 
									
										
										
										
											2008-12-19 03:05:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-31 13:28:01 -07:00
										 |  |  | 	if ok2 { | 
					
						
							| 
									
										
										
										
											2009-01-06 14:54:18 -08:00
										 |  |  | 		TypeChecker.CheckProgram(&err, prog); | 
					
						
							| 
									
										
										
										
											2008-12-16 18:02:22 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-04-16 20:52:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	// convert error list and sort it | 
					
						
							|  |  |  | 	errors := make(ErrorList, err.errors.Len()); | 
					
						
							|  |  |  | 	for i := 0; i < err.errors.Len(); i++ { | 
					
						
							|  |  |  | 		errors[i] = err.errors.At(i).(Error); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	sort.Sort(errors); | 
					
						
							| 
									
										
										
										
											2008-12-19 03:05:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 	return prog, errors; | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-24 14:08:01 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-15 17:16:41 -08:00
										 |  |  | func fileExists(name string) bool { | 
					
						
							| 
									
										
										
										
											2009-03-11 12:51:10 -07:00
										 |  |  | 	dir, err := os.Stat(name); | 
					
						
							| 
									
										
										
										
											2009-02-06 11:10:25 -08:00
										 |  |  | 	return err == nil; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-27 15:40:17 -08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | func printDep(localset map [string] bool, wset *vector.Vector, decl ast.Decl2) { | 
					
						
							|  |  |  | 	src := decl.Val.(*ast.BasicLit).Val; | 
					
						
							| 
									
										
										
										
											2009-02-06 11:10:25 -08:00
										 |  |  | 	src = src[1 : len(src) - 1];  // strip "'s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ignore files when they are seen a 2nd time | 
					
						
							|  |  |  | 	dummy, found := localset[src]; | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		localset[src] = true; | 
					
						
							|  |  |  | 		if fileExists(src + ".go") { | 
					
						
							|  |  |  | 			wset.Push(src); | 
					
						
							|  |  |  | 			fmt.Printf(" %s.6", src); | 
					
						
							|  |  |  | 		} else if | 
					
						
							|  |  |  | 			fileExists(Platform.GOROOT + "/pkg/" + src + ".6") || | 
					
						
							|  |  |  | 			fileExists(Platform.GOROOT + "/pkg/" + src + ".a") { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			// TODO should collect these and print later | 
					
						
							|  |  |  | 			//print("missing file: ", src, "\n"); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-27 15:40:17 -08:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-13 15:07:56 -08:00
										 |  |  | func addDeps(globalset map [string] bool, wset *vector.Vector, src_file string, flags *Flags) { | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 	dummy, found := globalset[src_file]; | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		globalset[src_file] = true; | 
					
						
							| 
									
										
										
										
											2008-12-19 03:05:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 		prog, errors := Compile(src_file, flags); | 
					
						
							|  |  |  | 		if errors == nil || len(errors) > 0 { | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-12-19 03:05:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-27 15:40:17 -08:00
										 |  |  | 		nimports := len(prog.Decls); | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 		if nimports > 0 { | 
					
						
							| 
									
										
										
										
											2009-02-06 11:10:25 -08:00
										 |  |  | 			fmt.Printf("%s.6:\t", src_file); | 
					
						
							| 
									
										
										
										
											2008-12-19 03:05:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-06 15:01:04 -08:00
										 |  |  | 			localset := make(map [string] bool); | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 			for i := 0; i < nimports; i++ { | 
					
						
							| 
									
										
										
										
											2009-02-27 15:40:17 -08:00
										 |  |  | 				decl := prog.Decls[i]; | 
					
						
							|  |  |  | 				panic(); | 
					
						
							|  |  |  | 				/* | 
					
						
							| 
									
										
										
										
											2009-03-11 12:52:11 -07:00
										 |  |  | 				assert(decl.Tok == scanner.IMPORT); | 
					
						
							| 
									
										
										
										
											2009-02-06 11:10:25 -08:00
										 |  |  | 				if decl.List == nil { | 
					
						
							|  |  |  | 					printDep(localset, wset, decl); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					for j := 0; j < decl.List.Len(); j++ { | 
					
						
							| 
									
										
										
										
											2009-03-13 16:59:51 -07:00
										 |  |  | 						printDep(localset, wset, decl.List.At(j).(*ast.Decl)); | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-02-27 15:40:17 -08:00
										 |  |  | 				*/ | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			print("\n\n"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-20 14:40:40 -08:00
										 |  |  | func ComputeDeps(src_file string, flags *Flags) { | 
					
						
							| 
									
										
										
										
											2009-03-05 17:15:36 -08:00
										 |  |  | 	panic("dependency printing currently disabled"); | 
					
						
							| 
									
										
										
										
											2009-01-06 15:01:04 -08:00
										 |  |  | 	globalset := make(map [string] bool); | 
					
						
							| 
									
										
										
										
											2009-02-13 15:07:56 -08:00
										 |  |  | 	wset := vector.New(0); | 
					
						
							| 
									
										
										
										
											2009-02-06 15:26:30 -08:00
										 |  |  | 	wset.Push(Utils.TrimExt(src_file, ".go")); | 
					
						
							| 
									
										
										
										
											2008-11-19 16:49:50 -08:00
										 |  |  | 	for wset.Len() > 0 { | 
					
						
							| 
									
										
										
										
											2009-01-15 17:16:41 -08:00
										 |  |  | 		addDeps(globalset, wset, wset.Pop().(string), flags); | 
					
						
							| 
									
										
										
										
											2008-10-26 21:32:30 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-10-24 14:08:01 -07:00
										 |  |  | } |