go_types/
package.rs

1// Copyright 2022 The Goscript Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4//
5//
6// This code is adapted from the offical Go code written in Go
7// with license as follows:
8// Copyright 2013 The Go Authors. All rights reserved.
9// Use of this source code is governed by a BSD-style
10// license that can be found in the LICENSE file.
11
12#![allow(dead_code)]
13use super::objects::{PackageKey, ScopeKey};
14use std::borrow::Cow;
15use std::fmt;
16
17/// A Package describes a Go package.
18#[derive(Debug)]
19pub struct Package {
20    path: String,
21    name: Option<String>,
22    scope: ScopeKey,
23    complete: bool,
24    imports: Vec<PackageKey>,
25    // scope lookup errors are silently dropped if package is fake (internal use only)
26    fake: bool,
27}
28
29impl Package {
30    pub fn new(path: String, name: Option<String>, scope: ScopeKey) -> Package {
31        Package {
32            path: path,
33            name: name,
34            scope: scope,
35            complete: false,
36            imports: Vec::new(),
37            fake: false,
38        }
39    }
40
41    pub fn path(&self) -> &String {
42        &self.path
43    }
44
45    pub fn name(&self) -> &Option<String> {
46        &self.name
47    }
48
49    pub fn set_name(&mut self, name: String) {
50        self.name = Some(name)
51    }
52
53    /// Scope returns the (complete or incomplete) package scope
54    /// holding the objects declared at package level (TypeNames,
55    /// Consts, Vars, and Funcs).
56    pub fn scope(&self) -> &ScopeKey {
57        &self.scope
58    }
59
60    /// A package is complete if its scope contains (at least) all
61    /// exported objects; otherwise it is incomplete.    
62    pub fn complete(&self) -> &bool {
63        &self.complete
64    }
65
66    pub fn mark_complete(&mut self) {
67        self.complete = true
68    }
69
70    pub fn fake(&self) -> &bool {
71        &self.fake
72    }
73
74    pub fn mark_fake_with_name(&mut self, name: String) {
75        self.fake = true;
76        self.name = Some(name);
77    }
78
79    /// Imports returns the list of packages directly imported by
80    /// pkg; the list is in source order.
81    ///
82    /// If pkg was loaded from export data, Imports includes packages that
83    /// provide package-level objects referenced by pkg. This may be more or
84    /// less than the set of packages directly imported by pkg's source code.
85    pub fn imports(&self) -> &Vec<PackageKey> {
86        &self.imports
87    }
88
89    pub fn imports_mut(&mut self) -> &mut Vec<PackageKey> {
90        &mut self.imports
91    }
92
93    pub fn add_import(&mut self, pkey: PackageKey) {
94        self.imports.push(pkey);
95    }
96
97    /// SetImports sets the list of explicitly imported packages to list.
98    /// It is the caller's responsibility to make sure list elements are unique.
99    pub fn set_imports(&mut self, pkgs: Vec<PackageKey>) {
100        self.imports = pkgs
101    }
102
103    pub fn fmt_with_qualifier(
104        &self,
105        f: &mut fmt::Formatter<'_>,
106        qf: &dyn Fn(&Package) -> Cow<str>,
107    ) -> fmt::Result {
108        write!(f, "{}.", qf(self))
109    }
110}
111
112impl fmt::Display for Package {
113    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114        if self.name.is_none() {
115            write!(f, "uninitialized package, path: {}", &self.path)
116        } else {
117            write!(
118                f,
119                "package {} ({})",
120                &self.name.as_ref().unwrap(),
121                &self.path
122            )
123        }
124    }
125}