github.com/goplus/igop@v0.25.0/importer.go (about) 1 /* 2 * Copyright (c) 2022 The GoPlus Authors (goplus.org). All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package igop 18 19 import ( 20 "fmt" 21 "go/importer" 22 "go/types" 23 ) 24 25 type Importer struct { 26 ctx *Context 27 pkgs map[string]*types.Package 28 importing map[string]bool 29 defaultImpl types.Importer 30 } 31 32 func NewImporter(ctx *Context) *Importer { 33 return &Importer{ 34 ctx: ctx, 35 pkgs: make(map[string]*types.Package), 36 importing: make(map[string]bool), 37 defaultImpl: importer.Default(), 38 } 39 } 40 41 func (i *Importer) Import(path string) (*types.Package, error) { 42 if pkg, ok := i.pkgs[path]; ok { 43 return pkg, nil 44 } 45 if i.importing[path] { 46 return nil, fmt.Errorf("cycle importing package %q", path) 47 } 48 i.importing[path] = true 49 defer func() { 50 i.importing[path] = false 51 }() 52 if pkg, err := i.ctx.Loader.Import(path); err == nil && pkg.Complete() { 53 i.pkgs[path] = pkg 54 return pkg, nil 55 } 56 if pkg, ok := i.ctx.pkgs[path]; ok { 57 if !pkg.Package.Complete() { 58 if err := pkg.Load(); err != nil { 59 return nil, err 60 } 61 } 62 i.pkgs[path] = pkg.Package 63 return pkg.Package, nil 64 } 65 if dir, found := i.ctx.lookupPath(path); found { 66 pkg, err := i.ctx.addImport(path, dir) 67 if err != nil { 68 return nil, err 69 } 70 if err := pkg.Load(); err != nil { 71 return nil, err 72 } 73 return pkg.Package, nil 74 } 75 return nil, ErrNotFoundPackage 76 }