func (tc *typechecker) checkNodesInNewScope(block ast.Node, nodes []ast.Node) []ast.Node {
	tc.scopes.Enter(block)
	nodes = tc.checkNodes(nodes)
	tc.scopes.Exit()
	return nodes
}
checkNodesInNewScope type checks nodes in a new scope. Panics on error.
package compiler
import (
	"fmt"
	"reflect"
	"strconv"
	"time"
	"github.com/open2b/scriggo/ast"
	"github.com/open2b/scriggo/internal/compiler/types"
	"github.com/open2b/scriggo/native"
)
var (
	stringerType    = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
	envStringerType = reflect.TypeOf((*native.EnvStringer)(nil)).Elem()
	htmlStringerType    = reflect.TypeOf((*native.HTMLStringer)(nil)).Elem()
	htmlEnvStringerType = reflect.TypeOf((*native.HTMLEnvStringer)(nil)).Elem()
	cssStringerType    = reflect.TypeOf((*native.CSSStringer)(nil)).Elem()
	cssEnvStringerType = reflect.TypeOf((*native.CSSEnvStringer)(nil)).Elem()
	jsStringerType    = reflect.TypeOf((*native.JSStringer)(nil)).Elem()
	jsEnvStringerType = reflect.TypeOf((*native.JSEnvStringer)(nil)).Elem()
	jsonStringerType    = reflect.TypeOf((*native.JSONStringer)(nil)).Elem()
	jsonEnvStringerType = reflect.TypeOf((*native.JSONEnvStringer)(nil)).Elem()
	mdStringerType    = reflect.TypeOf((*native.MarkdownStringer)(nil)).Elem()
	mdEnvStringerType = reflect.TypeOf((*native.MarkdownEnvStringer)(nil)).Elem()
)
func (tc *typechecker) templateFileToPackage(tree *ast.Tree) {
	if len(tree.Nodes) == 1 {
		if _, ok := tree.Nodes[0].(*ast.Package); ok {
			return
		}
	}
	var iteaToDeclarations map[string][]*ast.Identifier
	nodes := make([]ast.Node, 0, len(tree.Nodes)/2)
	for _, n := range tree.Nodes {
		switch n := n.(type) {
		case *ast.Text, *ast.Comment:
		case *ast.Extends, *ast.Import, *ast.Func, *ast.Var, *ast.Const, *ast.TypeDeclaration:
			nodes = append(nodes, n)
		case *ast.Statements:
			nodes = append(nodes, n.Nodes...)
		case *ast.Using:
			iteaName := tc.compilation.generateIteaName()
			iteaDeclaration, statement := tc.explodeUsingStatement(n, iteaName)
			nodes = append(nodes, iteaDeclaration, statement)
			if iteaToDeclarations == nil {
				iteaToDeclarations = map[string][]*ast.Identifier{}
			}
			if iteaHasBeenShadowed(tree.Nodes) {
				iteaToDeclarations[iteaName] = nil
			} else {
				iteaToDeclarations[iteaName] = n.Statement.(*ast.Var).Lhs
			}
		default:
			panic(internalError("unexpected node %s", n))
		}
	}
	pkg := ast.NewPackage(tree.Pos(), "", nodes)
	pkg.IR.IteaNameToVarIdents = iteaToDeclarations
	tree.Nodes = []ast.Node{pkg}
}
func iteaHasBeenShadowed(nodes []ast.Node) bool {
	for _, n := range nodes {
		switch n := n.(type) {
		case *ast.Var:
			for _, lh := range n.Lhs {
				if lh.Name == "itea" {
					return true
				}
			}
		case *ast.Func:
			if n.Ident.Name == "itea" {
				return true
			}
		case *ast.TypeDeclaration:
			if n.Ident.Name == "itea" {
				return true
			}
		case *ast.Const:
			for _, lh := range n.Lhs {
				if lh.Name == "itea" {
					return true
				}
			}
		case *ast.Import:
			if n.Ident != nil && n.Ident.Name == "itea" {
				return true
			}
		case *ast.Statements:
			if iteaHasBeenShadowed(n.Nodes) {
				return true
			}
		}
	}
	return false
}
func (tc *typechecker) checkNodesInNewScopeError(block ast.Node, nodes []ast.Node) (newNodes []ast.Node, err error) {
	defer func() {
		if r := recover(); r != nil {
			if rerr, ok := r.(*CheckingError); ok {
				err = rerr
			} else {
				panic(r)
			}
		}
	}()
	tc.scopes.Enter(block)
	newNodes = tc.checkNodes(nodes)
	tc.scopes.Exit()
	return
}