mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
refactor(isolated-declarations): protect internal transform methods (#6723)
Change `pub fn` to `pub(crate) fn` for all internal methods in isolated declarations. I would appreciate someone who is more familiar with this code informing me if I incorrectly privatized methods that should be public.
This commit is contained in:
parent
f05a2739da
commit
2e2b748285
8 changed files with 39 additions and 59 deletions
|
|
@ -15,7 +15,8 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'a> IsolatedDeclarations<'a> {
|
impl<'a> IsolatedDeclarations<'a> {
|
||||||
pub fn is_literal_key(&self, key: &PropertyKey<'a>) -> bool {
|
#[allow(clippy::unused_self)]
|
||||||
|
pub(crate) fn is_literal_key(&self, key: &PropertyKey<'a>) -> bool {
|
||||||
match key {
|
match key {
|
||||||
PropertyKey::StringLiteral(_)
|
PropertyKey::StringLiteral(_)
|
||||||
| PropertyKey::NumericLiteral(_)
|
| PropertyKey::NumericLiteral(_)
|
||||||
|
|
@ -32,7 +33,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn report_property_key(&self, key: &PropertyKey<'a>, computed: bool) -> bool {
|
pub(crate) fn report_property_key(&self, key: &PropertyKey<'a>, computed: bool) -> bool {
|
||||||
if computed && !self.is_literal_key(key) {
|
if computed && !self.is_literal_key(key) {
|
||||||
self.error(computed_property_name(key.span()));
|
self.error(computed_property_name(key.span()));
|
||||||
true
|
true
|
||||||
|
|
@ -41,7 +42,8 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_accessibility(
|
#[allow(clippy::unused_self)]
|
||||||
|
pub(crate) fn transform_accessibility(
|
||||||
&self,
|
&self,
|
||||||
accessibility: Option<TSAccessibility>,
|
accessibility: Option<TSAccessibility>,
|
||||||
) -> Option<TSAccessibility> {
|
) -> Option<TSAccessibility> {
|
||||||
|
|
@ -328,7 +330,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
method_annotations
|
method_annotations
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_class(
|
pub(crate) fn transform_class(
|
||||||
&self,
|
&self,
|
||||||
decl: &Class<'a>,
|
decl: &Class<'a>,
|
||||||
declare: Option<bool>,
|
declare: Option<bool>,
|
||||||
|
|
@ -557,7 +559,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_formal_parameters(
|
pub(crate) fn create_formal_parameters(
|
||||||
&self,
|
&self,
|
||||||
kind: BindingPatternKind<'a>,
|
kind: BindingPatternKind<'a>,
|
||||||
) -> Box<'a, FormalParameters<'a>> {
|
) -> Box<'a, FormalParameters<'a>> {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'a> IsolatedDeclarations<'a> {
|
impl<'a> IsolatedDeclarations<'a> {
|
||||||
pub fn transform_variable_declaration(
|
pub(crate) fn transform_variable_declaration(
|
||||||
&self,
|
&self,
|
||||||
decl: &VariableDeclaration<'a>,
|
decl: &VariableDeclaration<'a>,
|
||||||
check_binding: bool,
|
check_binding: bool,
|
||||||
|
|
@ -37,7 +37,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_variable_declaration_with_new_declarations(
|
pub(crate) fn transform_variable_declaration_with_new_declarations(
|
||||||
&self,
|
&self,
|
||||||
decl: &VariableDeclaration<'a>,
|
decl: &VariableDeclaration<'a>,
|
||||||
declarations: oxc_allocator::Vec<'a, VariableDeclarator<'a>>,
|
declarations: oxc_allocator::Vec<'a, VariableDeclarator<'a>>,
|
||||||
|
|
@ -50,7 +50,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_variable_declarator(
|
pub(crate) fn transform_variable_declarator(
|
||||||
&self,
|
&self,
|
||||||
decl: &VariableDeclarator<'a>,
|
decl: &VariableDeclarator<'a>,
|
||||||
check_binding: bool,
|
check_binding: bool,
|
||||||
|
|
@ -117,31 +117,6 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
Some(self.ast.variable_declarator(decl.span, decl.kind, id, init, decl.definite))
|
Some(self.ast.variable_declarator(decl.span, decl.kind, id, init, decl.definite))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_using_declaration(
|
|
||||||
&self,
|
|
||||||
decl: &VariableDeclaration<'a>,
|
|
||||||
check_binding: bool,
|
|
||||||
) -> Box<'a, VariableDeclaration<'a>> {
|
|
||||||
let declarations =
|
|
||||||
self.ast.vec_from_iter(decl.declarations.iter().filter_map(|declarator| {
|
|
||||||
self.transform_variable_declarator(declarator, check_binding)
|
|
||||||
}));
|
|
||||||
self.transform_using_declaration_with_new_declarations(decl, declarations)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn transform_using_declaration_with_new_declarations(
|
|
||||||
&self,
|
|
||||||
decl: &VariableDeclaration<'a>,
|
|
||||||
declarations: oxc_allocator::Vec<'a, VariableDeclarator<'a>>,
|
|
||||||
) -> Box<'a, VariableDeclaration<'a>> {
|
|
||||||
self.ast.alloc_variable_declaration(
|
|
||||||
decl.span,
|
|
||||||
VariableDeclarationKind::Const,
|
|
||||||
declarations,
|
|
||||||
self.is_declare(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform_ts_module_block(
|
fn transform_ts_module_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
block: &Box<'a, TSModuleBlock<'a>>,
|
block: &Box<'a, TSModuleBlock<'a>>,
|
||||||
|
|
@ -154,7 +129,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
self.ast.alloc_ts_module_block(SPAN, self.ast.vec(), stmts)
|
self.ast.alloc_ts_module_block(SPAN, self.ast.vec(), stmts)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_ts_module_declaration(
|
pub(crate) fn transform_ts_module_declaration(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &Box<'a, TSModuleDeclaration<'a>>,
|
decl: &Box<'a, TSModuleDeclaration<'a>>,
|
||||||
) -> Box<'a, TSModuleDeclaration<'a>> {
|
) -> Box<'a, TSModuleDeclaration<'a>> {
|
||||||
|
|
@ -194,7 +169,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_declaration(
|
pub(crate) fn transform_declaration(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &Declaration<'a>,
|
decl: &Declaration<'a>,
|
||||||
check_binding: bool,
|
check_binding: bool,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'a> IsolatedDeclarations<'a> {
|
impl<'a> IsolatedDeclarations<'a> {
|
||||||
pub fn transform_function(
|
pub(crate) fn transform_function(
|
||||||
&mut self,
|
&mut self,
|
||||||
func: &Function<'a>,
|
func: &Function<'a>,
|
||||||
declare: Option<bool>,
|
declare: Option<bool>,
|
||||||
|
|
@ -45,7 +45,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_formal_parameter(
|
pub(crate) fn transform_formal_parameter(
|
||||||
&self,
|
&self,
|
||||||
param: &FormalParameter<'a>,
|
param: &FormalParameter<'a>,
|
||||||
is_remaining_params_have_required: bool,
|
is_remaining_params_have_required: bool,
|
||||||
|
|
@ -124,7 +124,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
Some(self.ast.formal_parameter(param.span, self.ast.vec(), pattern, None, false, false))
|
Some(self.ast.formal_parameter(param.span, self.ast.vec(), pattern, None, false, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_formal_parameters(
|
pub(crate) fn transform_formal_parameters(
|
||||||
&self,
|
&self,
|
||||||
params: &FormalParameters<'a>,
|
params: &FormalParameters<'a>,
|
||||||
) -> Box<'a, FormalParameters<'a>> {
|
) -> Box<'a, FormalParameters<'a>> {
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'a> IsolatedDeclarations<'a> {
|
impl<'a> IsolatedDeclarations<'a> {
|
||||||
pub fn can_infer_unary_expression(expr: &UnaryExpression<'a>) -> bool {
|
pub(crate) fn can_infer_unary_expression(expr: &UnaryExpression<'a>) -> bool {
|
||||||
expr.operator.is_arithmetic() && expr.argument.is_number_literal()
|
expr.operator.is_arithmetic() && expr.argument.is_number_literal()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer_type_from_expression(&self, expr: &Expression<'a>) -> Option<TSType<'a>> {
|
pub(crate) fn infer_type_from_expression(&self, expr: &Expression<'a>) -> Option<TSType<'a>> {
|
||||||
match expr {
|
match expr {
|
||||||
Expression::BooleanLiteral(_) => Some(self.ast.ts_type_boolean_keyword(SPAN)),
|
Expression::BooleanLiteral(_) => Some(self.ast.ts_type_boolean_keyword(SPAN)),
|
||||||
Expression::NullLiteral(_) => Some(self.ast.ts_type_null_keyword(SPAN)),
|
Expression::NullLiteral(_) => Some(self.ast.ts_type_null_keyword(SPAN)),
|
||||||
|
|
@ -84,7 +84,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer_type_from_formal_parameter(
|
pub(crate) fn infer_type_from_formal_parameter(
|
||||||
&self,
|
&self,
|
||||||
param: &FormalParameter<'a>,
|
param: &FormalParameter<'a>,
|
||||||
) -> Option<TSType<'a>> {
|
) -> Option<TSType<'a>> {
|
||||||
|
|
@ -106,7 +106,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer_function_return_type(
|
pub(crate) fn infer_function_return_type(
|
||||||
&self,
|
&self,
|
||||||
function: &Function<'a>,
|
function: &Function<'a>,
|
||||||
) -> Option<Box<'a, TSTypeAnnotation<'a>>> {
|
) -> Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||||
|
|
@ -125,7 +125,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infer_arrow_function_return_type(
|
pub(crate) fn infer_arrow_function_return_type(
|
||||||
&self,
|
&self,
|
||||||
function: &ArrowFunctionExpression<'a>,
|
function: &ArrowFunctionExpression<'a>,
|
||||||
) -> Option<Box<'a, TSTypeAnnotation<'a>>> {
|
) -> Option<Box<'a, TSTypeAnnotation<'a>>> {
|
||||||
|
|
@ -150,7 +150,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
.map(|type_annotation| self.ast.alloc_ts_type_annotation(SPAN, type_annotation))
|
.map(|type_annotation| self.ast.alloc_ts_type_annotation(SPAN, type_annotation))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_need_to_infer_type_from_expression(expr: &Expression<'a>) -> bool {
|
pub(crate) fn is_need_to_infer_type_from_expression(expr: &Expression<'a>) -> bool {
|
||||||
match expr {
|
match expr {
|
||||||
Expression::NumericLiteral(_)
|
Expression::NumericLiteral(_)
|
||||||
| Expression::BigIntLiteral(_)
|
| Expression::BigIntLiteral(_)
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IsolatedDeclarations<'a> {
|
impl<'a> IsolatedDeclarations<'a> {
|
||||||
pub fn transform_program(
|
fn transform_program(
|
||||||
&mut self,
|
&mut self,
|
||||||
program: &Program<'a>,
|
program: &Program<'a>,
|
||||||
) -> oxc_allocator::Vec<'a, Statement<'a>> {
|
) -> oxc_allocator::Vec<'a, Statement<'a>> {
|
||||||
|
|
@ -152,7 +152,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_program_without_module_declaration(
|
fn transform_program_without_module_declaration(
|
||||||
&mut self,
|
&mut self,
|
||||||
stmts: &oxc_allocator::Vec<'a, Statement<'a>>,
|
stmts: &oxc_allocator::Vec<'a, Statement<'a>>,
|
||||||
) -> oxc_allocator::Vec<'a, Statement<'a>> {
|
) -> oxc_allocator::Vec<'a, Statement<'a>> {
|
||||||
|
|
@ -175,7 +175,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::missing_panics_doc)]
|
#[allow(clippy::missing_panics_doc)]
|
||||||
pub fn transform_statements_on_demand(
|
fn transform_statements_on_demand(
|
||||||
&mut self,
|
&mut self,
|
||||||
stmts: &oxc_allocator::Vec<'a, Statement<'a>>,
|
stmts: &oxc_allocator::Vec<'a, Statement<'a>>,
|
||||||
) -> oxc_allocator::Vec<'a, Statement<'a>> {
|
) -> oxc_allocator::Vec<'a, Statement<'a>> {
|
||||||
|
|
@ -421,7 +421,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
new_stm
|
new_stm
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_function_overloads_implementation(
|
fn remove_function_overloads_implementation(
|
||||||
stmts: &mut oxc_allocator::Vec<'a, &Statement<'a>>,
|
stmts: &mut oxc_allocator::Vec<'a, &Statement<'a>>,
|
||||||
) {
|
) {
|
||||||
let mut last_function_name: Option<Atom<'a>> = None;
|
let mut last_function_name: Option<Atom<'a>> = None;
|
||||||
|
|
@ -556,7 +556,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
assignable_properties_for_namespace
|
assignable_properties_for_namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn report_error_for_expando_function(&self, stmts: &oxc_allocator::Vec<'a, Statement<'a>>) {
|
fn report_error_for_expando_function(&self, stmts: &oxc_allocator::Vec<'a, Statement<'a>>) {
|
||||||
let assignable_properties_for_namespace =
|
let assignable_properties_for_namespace =
|
||||||
IsolatedDeclarations::get_assignable_properties_for_namespaces(stmts);
|
IsolatedDeclarations::get_assignable_properties_for_namespaces(stmts);
|
||||||
|
|
||||||
|
|
@ -644,7 +644,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_declare(&self) -> bool {
|
fn is_declare(&self) -> bool {
|
||||||
// If we are in a module block, we don't need to add declare
|
// If we are in a module block, we don't need to add declare
|
||||||
!self.scope.is_ts_module_block()
|
!self.scope.is_ts_module_block()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use oxc_ast::ast::{StringLiteral, TemplateLiteral};
|
||||||
use crate::IsolatedDeclarations;
|
use crate::IsolatedDeclarations;
|
||||||
|
|
||||||
impl<'a> IsolatedDeclarations<'a> {
|
impl<'a> IsolatedDeclarations<'a> {
|
||||||
pub fn transform_template_to_string(
|
pub(crate) fn transform_template_to_string(
|
||||||
&self,
|
&self,
|
||||||
lit: &TemplateLiteral<'a>,
|
lit: &TemplateLiteral<'a>,
|
||||||
) -> Option<Box<'a, StringLiteral<'a>>> {
|
) -> Option<Box<'a, StringLiteral<'a>>> {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use oxc_span::{Atom, GetSpan, SPAN};
|
||||||
use crate::{diagnostics::default_export_inferred, IsolatedDeclarations};
|
use crate::{diagnostics::default_export_inferred, IsolatedDeclarations};
|
||||||
|
|
||||||
impl<'a> IsolatedDeclarations<'a> {
|
impl<'a> IsolatedDeclarations<'a> {
|
||||||
pub fn transform_export_named_declaration(
|
pub(crate) fn transform_export_named_declaration(
|
||||||
&mut self,
|
&mut self,
|
||||||
prev_decl: &ExportNamedDeclaration<'a>,
|
prev_decl: &ExportNamedDeclaration<'a>,
|
||||||
) -> Option<ExportNamedDeclaration<'a>> {
|
) -> Option<ExportNamedDeclaration<'a>> {
|
||||||
|
|
@ -23,7 +23,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_unique_name(&mut self, name: &str) -> Atom<'a> {
|
pub(crate) fn create_unique_name(&mut self, name: &str) -> Atom<'a> {
|
||||||
let mut binding = self.ast.atom(name);
|
let mut binding = self.ast.atom(name);
|
||||||
let mut i = 1;
|
let mut i = 1;
|
||||||
while self.scope.has_reference(&binding) {
|
while self.scope.has_reference(&binding) {
|
||||||
|
|
@ -33,7 +33,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
binding
|
binding
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_export_default_declaration(
|
pub(crate) fn transform_export_default_declaration(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &ExportDefaultDeclaration<'a>,
|
decl: &ExportDefaultDeclaration<'a>,
|
||||||
) -> Option<(Option<VariableDeclaration<'a>>, ExportDefaultDeclaration<'a>)> {
|
) -> Option<(Option<VariableDeclaration<'a>>, ExportDefaultDeclaration<'a>)> {
|
||||||
|
|
@ -91,7 +91,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_import_declaration(
|
pub(crate) fn transform_import_declaration(
|
||||||
&self,
|
&self,
|
||||||
decl: &ImportDeclaration<'a>,
|
decl: &ImportDeclaration<'a>,
|
||||||
) -> Option<Box<'a, ImportDeclaration<'a>>> {
|
) -> Option<Box<'a, ImportDeclaration<'a>>> {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<'a> IsolatedDeclarations<'a> {
|
impl<'a> IsolatedDeclarations<'a> {
|
||||||
pub fn transform_function_to_ts_type(&self, func: &Function<'a>) -> Option<TSType<'a>> {
|
pub(crate) fn transform_function_to_ts_type(&self, func: &Function<'a>) -> Option<TSType<'a>> {
|
||||||
let return_type = self.infer_function_return_type(func);
|
let return_type = self.infer_function_return_type(func);
|
||||||
if return_type.is_none() {
|
if return_type.is_none() {
|
||||||
self.error(function_must_have_explicit_return_type(get_function_span(func)));
|
self.error(function_must_have_explicit_return_type(get_function_span(func)));
|
||||||
|
|
@ -39,7 +39,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_arrow_function_to_ts_type(
|
pub(crate) fn transform_arrow_function_to_ts_type(
|
||||||
&self,
|
&self,
|
||||||
func: &ArrowFunctionExpression<'a>,
|
func: &ArrowFunctionExpression<'a>,
|
||||||
) -> Option<TSType<'a>> {
|
) -> Option<TSType<'a>> {
|
||||||
|
|
@ -148,7 +148,7 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
self.ast.ts_type_type_literal(SPAN, members)
|
self.ast.ts_type_type_literal(SPAN, members)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_array_expression_to_ts_type(
|
pub(crate) fn transform_array_expression_to_ts_type(
|
||||||
&self,
|
&self,
|
||||||
expr: &ArrayExpression<'a>,
|
expr: &ArrayExpression<'a>,
|
||||||
is_const: bool,
|
is_const: bool,
|
||||||
|
|
@ -181,7 +181,10 @@ impl<'a> IsolatedDeclarations<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions
|
// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions
|
||||||
pub fn transform_expression_to_ts_type(&self, expr: &Expression<'a>) -> Option<TSType<'a>> {
|
pub(crate) fn transform_expression_to_ts_type(
|
||||||
|
&self,
|
||||||
|
expr: &Expression<'a>,
|
||||||
|
) -> Option<TSType<'a>> {
|
||||||
match expr {
|
match expr {
|
||||||
Expression::BooleanLiteral(lit) => Some(self.ast.ts_type_literal_type(
|
Expression::BooleanLiteral(lit) => Some(self.ast.ts_type_literal_type(
|
||||||
SPAN,
|
SPAN,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue