2019-07-28 23:53:15 +03:00
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
2015-06-01 22:15:17 +03:00
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System ;
2015-05-14 22:35:07 +03:00
using System.IO ;
using System.Collections ;
using System.Reflection ;
using TreeConverter ;
using SymbolTable ;
using PascalABCCompiler.TreeConverter ;
using PascalABCCompiler.TreeRealization ;
2018-04-14 18:18:42 +03:00
using System.Collections.Generic ;
2015-05-14 22:35:07 +03:00
namespace PascalABCCompiler.PCU
{
/ * public interface IWrappedNodeWithOffset
{
public PCUReader pcuReader
{
get ;
set ;
}
public int offset
{
get ;
set ;
}
} * /
public class WrappedUnitInterfaceScope : UnitInterfaceScope
{
protected PCUReader pr ;
public WrappedUnitInterfaceScope ( PCUReader pr )
2018-05-07 02:20:08 +03:00
: base ( PascalABCCompiler . SystemLibrary . SystemLibrary . symtab , null , new Scope [ 0 ] { } , "" )
2015-05-14 22:35:07 +03:00
{
this . pr = pr ;
2018-05-07 02:20:08 +03:00
Name = Path . GetFileName ( pr . FileName ) ;
2015-05-14 22:35:07 +03:00
}
2018-04-14 18:18:42 +03:00
public override List < SymbolInfo > Find ( string name )
2015-05-14 22:35:07 +03:00
{
2018-04-14 18:18:42 +03:00
List < SymbolInfo > sil = SymbolTable . Find ( this , name ) ;
2017-10-23 11:21:15 +03:00
if ( sil = = null ) return null ;
2018-04-14 18:18:42 +03:00
foreach ( SymbolInfo tsi in sil )
2015-05-14 22:35:07 +03:00
{
if ( tsi . sym_info . semantic_node_type = = semantic_node_type . wrap_def )
{
wrapped_definition_node wdn = ( wrapped_definition_node ) tsi . sym_info ;
if ( wdn . is_synonim )
tsi . sym_info = wdn . PCUReader . CreateTypeSynonim ( wdn . offset , name ) ;
else
tsi . sym_info = wdn . PCUReader . CreateInterfaceMember ( wdn . offset , name ) ;
}
}
2017-10-23 11:21:15 +03:00
return sil ;
2015-05-14 22:35:07 +03:00
}
2018-04-14 18:18:42 +03:00
public override List < SymbolInfo > FindOnlyInScope ( string name )
2015-05-14 22:35:07 +03:00
{
2018-04-14 18:18:42 +03:00
List < SymbolInfo > sil = SymbolTable . FindOnlyInScope ( this , name , false ) ;
2017-05-09 12:52:40 +03:00
2017-10-23 11:21:15 +03:00
if ( sil = = null ) return sil ;
2018-04-14 18:18:42 +03:00
foreach ( SymbolInfo tsi in sil )
2015-05-14 22:35:07 +03:00
{
if ( tsi . sym_info . semantic_node_type = = semantic_node_type . wrap_def )
{
wrapped_definition_node wdn = ( wrapped_definition_node ) tsi . sym_info ;
if ( wdn . is_synonim )
2017-05-09 12:52:40 +03:00
tsi . sym_info = wdn . PCUReader . CreateTypeSynonim ( wdn . offset , name ) ;
2015-05-14 22:35:07 +03:00
else
2017-05-30 22:44:10 +03:00
tsi . sym_info = wdn . PCUReader . CreateInterfaceMember ( wdn . offset , name ) ;
2015-05-14 22:35:07 +03:00
}
}
2017-10-23 11:21:15 +03:00
return sil ;
2015-05-14 22:35:07 +03:00
}
//нужно для перегруженных методов
2018-04-14 18:18:42 +03:00
public List < SymbolInfo > FindWithoutCreation ( string name )
2015-05-14 22:35:07 +03:00
{
return SymbolTable . FindOnlyInType ( this , name ) ;
}
}
//ssyy
public class WrappedUnitImplementationScope : UnitImplementationScope
{
protected PCUReader pr ;
public WrappedUnitImplementationScope ( PCUReader pr , Scope TopScope )
2018-05-07 02:20:08 +03:00
: base ( PascalABCCompiler . SystemLibrary . SystemLibrary . symtab , TopScope , new Scope [ 0 ] { } , "" )
2015-05-14 22:35:07 +03:00
{
this . pr = pr ;
}
2018-04-14 18:18:42 +03:00
public override List < SymbolInfo > Find ( string name )
2015-05-14 22:35:07 +03:00
{
2018-04-14 18:18:42 +03:00
List < SymbolInfo > sil = SymbolTable . Find ( this , name ) ;
2017-10-23 11:21:15 +03:00
if ( sil = = null ) return null ;
2018-04-14 18:18:42 +03:00
foreach ( SymbolInfo tsi in sil )
2015-05-14 22:35:07 +03:00
{
if ( tsi . sym_info . semantic_node_type = = semantic_node_type . wrap_def )
{
wrapped_definition_node wdn = ( wrapped_definition_node ) tsi . sym_info ;
if ( wdn . is_synonim )
tsi . sym_info = wdn . PCUReader . CreateTypeSynonim ( wdn . offset , name ) ;
else
tsi . sym_info = wdn . PCUReader . CreateImplementationMember ( wdn . offset ) ;
}
}
2017-10-23 11:21:15 +03:00
return sil ;
2015-05-14 22:35:07 +03:00
}
2018-04-14 18:18:42 +03:00
public override List < SymbolInfo > FindOnlyInScope ( string name )
2015-05-14 22:35:07 +03:00
{
2018-04-14 18:18:42 +03:00
List < SymbolInfo > sil = SymbolTable . FindOnlyInScope ( this , name , false ) ;
2017-05-09 12:52:40 +03:00
2017-10-23 11:21:15 +03:00
if ( sil = = null ) return sil ;
2018-04-14 18:18:42 +03:00
foreach ( SymbolInfo tsi in sil )
2015-05-14 22:35:07 +03:00
{
if ( tsi . sym_info . semantic_node_type = = semantic_node_type . wrap_def )
{
wrapped_definition_node wdn = ( wrapped_definition_node ) tsi . sym_info ;
if ( wdn . is_synonim )
2017-05-09 12:52:40 +03:00
tsi . sym_info = wdn . PCUReader . CreateTypeSynonim ( wdn . offset , name ) ;
2015-05-14 22:35:07 +03:00
else
2017-05-09 12:52:40 +03:00
tsi . sym_info = wdn . PCUReader . CreateImplementationMember ( wdn . offset ) ;
2015-05-14 22:35:07 +03:00
}
}
2017-10-23 11:21:15 +03:00
return sil ;
2015-05-14 22:35:07 +03:00
}
//нужно для перегруженных методов
2018-04-14 18:18:42 +03:00
public List < SymbolInfo > FindWithoutCreation ( string name )
2015-05-14 22:35:07 +03:00
{
return SymbolTable . FindOnlyInType ( this , name ) ;
}
}
//\ssyy
public class WrappedClassScope : ClassScope
{
protected PCUReader pr ;
2020-03-08 13:58:48 +03:00
internal common_type_node ctn ;
2015-05-14 22:35:07 +03:00
public WrappedClassScope ( PCUReader pr , Scope top_scope , Scope up_scope )
2018-05-07 02:20:08 +03:00
: base ( SystemLibrary . SystemLibrary . symtab , top_scope , up_scope , "" )
2015-05-14 22:35:07 +03:00
{
this . pr = pr ;
}
2018-04-14 18:18:42 +03:00
public override List < SymbolInfo > Find ( string name )
2015-05-14 22:35:07 +03:00
{
2018-04-14 18:18:42 +03:00
List < SymbolInfo > sil = SymbolTable . Find ( this , name ) ;
2015-05-14 22:35:07 +03:00
if ( PartialScope ! = null )
{
2017-10-23 11:21:15 +03:00
if ( sil = = null )
sil = SymbolTable . Find ( PartialScope , name ) ;
2015-05-14 22:35:07 +03:00
else
2018-04-14 18:18:42 +03:00
sil . AddRange ( SymbolTable . Find ( PartialScope , name ) ) ;
2015-05-14 22:35:07 +03:00
}
2017-10-23 11:21:15 +03:00
if ( sil = = null ) return sil ;
2015-05-14 22:35:07 +03:00
//если это заглушка, то разворачиваем сущность
2018-04-14 18:18:42 +03:00
foreach ( SymbolInfo tsi in sil )
2015-05-14 22:35:07 +03:00
{
if ( tsi . sym_info . semantic_node_type = = semantic_node_type . wrap_def )
{
wrapped_definition_node wdn = ( wrapped_definition_node ) tsi . sym_info ;
tsi . sym_info = wdn . PCUReader . CreateInterfaceInClassMember ( wdn . offset , name ) ;
}
}
2017-10-23 11:21:15 +03:00
return sil ;
2015-05-14 22:35:07 +03:00
}
2020-03-08 13:58:48 +03:00
private bool hasNotRestoreAttribute ( )
{
if ( ctn = = null )
return false ;
foreach ( var attr in ctn . attributes )
{
if ( string . Compare ( attr . attribute_type . full_name , "PABCSystem.PCUNotRestoreAttribute" , true ) = = 0 )
return true ;
}
return false ;
}
2020-03-11 21:46:53 +03:00
private bool needRestore ( PCUSymbolInfo pcu_tsi , string name )
{
if ( pcu_tsi = = null )
return true ;
if ( pcu_tsi . semantic_node_type = = semantic_node_type . common_method_node & & pcu_tsi . virtual_slot )
return true ;
if ( hasNotRestoreAttribute ( ) )
return false ;
if ( pcu_tsi . is_static )
return false ;
if ( pcu_tsi . semantic_node_type = = semantic_node_type . common_method_node )
return false ;
return true ;
}
2015-05-14 22:35:07 +03:00
public void RestoreMembers ( string name )
{
2018-04-14 18:18:42 +03:00
List < SymbolInfo > sil = SymbolTable . FindOnlyInThisClass ( this , name ) ;
2015-05-14 22:35:07 +03:00
//если это заглушка, то разворачиваем сущность
2018-04-14 18:18:42 +03:00
foreach ( SymbolInfo tsi in sil )
2015-05-14 22:35:07 +03:00
{
if ( tsi . sym_info . semantic_node_type = = semantic_node_type . wrap_def )
{
2017-05-20 21:20:02 +03:00
PCUSymbolInfo pcu_tsi = tsi as PCUSymbolInfo ;
2020-03-11 21:46:53 +03:00
if ( needRestore ( pcu_tsi , name ) | | pr . comp . CompilerOptions . OutputFileType = = CompilerOptions . OutputType . ClassLibrary | | name = = "op_Equality" | | name = = "op_Inequality" )
2015-05-14 22:35:07 +03:00
{
wrapped_definition_node wdn = ( wrapped_definition_node ) tsi . sym_info ;
tsi . sym_info = wdn . PCUReader . CreateInterfaceInClassMember ( wdn . offset , name ) ;
}
else
{
}
}
}
}
2018-04-14 18:18:42 +03:00
public override List < SymbolInfo > Find ( string name , Scope CurrentScope )
2015-05-14 22:35:07 +03:00
{
return Find ( name ) ;
}
2018-04-14 18:18:42 +03:00
public List < SymbolInfo > FindWithoutCreation ( string name )
2015-05-14 22:35:07 +03:00
{
2017-05-30 22:44:10 +03:00
return SymbolTable . FindOnlyInScope ( this , name , false ) ;
2015-05-14 22:35:07 +03:00
}
}
//ssyy
public class WrappedInterfaceScope : WrappedClassScope , IInterfaceScope
{
private Scope [ ] _TopInterfaceScopeArray ;
public virtual Scope [ ] TopInterfaceScopeArray
{
get
{
return _TopInterfaceScopeArray ;
}
set
{
_TopInterfaceScopeArray = value ;
}
}
public WrappedInterfaceScope ( PCUReader pr , Scope TopScope , Scope [ ] vTopInterfaceScopeArray )
:
base ( pr , TopScope , null )
{
_TopInterfaceScopeArray = vTopInterfaceScopeArray ;
}
public WrappedInterfaceScope ( PCUReader pr , Scope TopScope , Scope BaseClassScope , Scope [ ] vTopInterfaceScopeArray )
:
base ( pr , TopScope , BaseClassScope )
{
_TopInterfaceScopeArray = vTopInterfaceScopeArray ;
}
}
//\ssyy
public class wrapped_type_synonym : wrapped_definition_node
{
public string name ;
public wrapped_type_synonym ( PCUReader pr , string name , int offset ) : base ( offset , pr )
{
this . name = name ;
is_synonim = true ;
}
}
2017-05-20 21:20:02 +03:00
public class wrapped_expression : expression_node
{
private PCUReader pr ;
public int offset ;
public wrapped_expression ( PCUReader pr , int offset )
{
this . pr = pr ;
this . offset = offset ;
}
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type . wrapped_expression ;
}
}
public expression_node restore ( )
{
return pr . GetExpression ( offset ) ;
}
}
2015-05-14 22:35:07 +03:00
public class wrapped_function_body : wrapped_statement
{
private PCUReader pr ;
public int offset ;
public wrapped_function_body ( PCUReader pr , int offset ) : base ( null )
{
this . pr = pr ;
this . offset = offset ;
}
public override statement_node restore ( )
{
return pr . GetCode ( offset ) ;
}
}
public class wrapped_common_type_node : common_type_node
{
private PCUReader pr ;
public int offset ;
public wrapped_common_type_node ( PCUReader pr , type_node base_type , string name , SemanticTree . type_access_level type_access_level ,
2016-05-16 21:45:03 +03:00
common_namespace_node comprehensive_namespace , SymbolTable . ClassScope cs , location loc , int offset ) :
base ( base_type , name , type_access_level , comprehensive_namespace , cs , loc )
2015-05-14 22:35:07 +03:00
{
this . pr = pr ;
this . offset = offset ;
}
2018-04-14 18:18:42 +03:00
public override List < SymbolInfo > find_in_type ( string name , bool no_search_in_extension_methods = false )
2015-05-14 22:35:07 +03:00
{
2019-02-01 15:04:07 +03:00
return find_in_type ( name , null , null , no_search_in_extension_methods ) ;
2015-05-14 22:35:07 +03:00
}
2019-02-01 15:04:07 +03:00
public override List < SymbolInfo > find_in_type ( string name , Scope CurrentScope , type_node orig_generic_or_null = null , bool no_search_in_extension_methods = false )
2015-05-14 22:35:07 +03:00
{
2018-04-14 18:18:42 +03:00
List < SymbolInfo > sil = scope . FindOnlyInType ( name , CurrentScope ) ;
2017-10-23 11:21:15 +03:00
if ( sil = = null )
2015-05-14 22:35:07 +03:00
{
2017-05-20 21:20:02 +03:00
if ( base_type ! = null & & base_type . IsDelegate )
2019-02-01 15:04:07 +03:00
return base_type . find_in_type ( name , CurrentScope , null , no_search_in_extension_methods ) ;
2018-06-03 20:49:55 +03:00
else if ( name = = compiler_string_consts . deconstruct_method_name )
2019-02-01 15:04:07 +03:00
return SystemLibrary . SystemLibrary . object_type . find_in_type ( name , CurrentScope , null , no_search_in_extension_methods ) ;
2020-02-14 19:47:41 +03:00
// SSM перенес из common_type_node (types.cs 2116) - без этого не работали методы расширения последовательностей для типов в pcu, реализующих IEnumerable<T>
if ( ImplementingInterfaces ! = null )
{
Dictionary < definition_node , definition_node > cache = new Dictionary < definition_node , definition_node > ( ) ;
List < SymbolInfo > props = new List < SymbolInfo > ( ) ;
foreach ( type_node ii_tn in ImplementingInterfaces )
{
List < SymbolInfo > isi = ii_tn . find_in_type ( name , CurrentScope ) ;
if ( isi ! = null )
{
if ( sil = = null )
sil = new List < SymbolInfo > ( ) ;
foreach ( SymbolInfo si in isi )
{
if ( ! cache . ContainsKey ( si . sym_info ) )
{
if ( si . sym_info is function_node & & ( si . sym_info as function_node ) . is_extension_method
& & sil . FindIndex ( ssi = > ssi . sym_info = = si . sym_info ) = = - 1 ) // SSM 12.12.18 - за счёт методов интерфейсов тоже могут добавляться одинаковые - исключаем их
sil . Add ( si ) ;
cache . Add ( si . sym_info , si . sym_info ) ;
}
}
}
}
if ( sil ! = null & & sil . Count = = 0 )
sil = null ;
}
2017-10-23 11:21:15 +03:00
return sil ;
2017-05-20 21:20:02 +03:00
}
2020-03-15 15:28:55 +03:00
if ( this . base_generic_instance ! = null & & sil ! = null )
{
var bsil = base_generic_instance . ConvertSymbolInfo ( sil ) ;
2020-08-17 17:55:39 +03:00
if ( orig_generic_or_null = = null & & name ! = "op_Implicit" )
2020-03-15 15:28:55 +03:00
return bsil ;
}
foreach ( SymbolInfo si in sil )
2017-05-20 21:20:02 +03:00
{
2017-10-23 11:21:15 +03:00
if ( si . sym_info . semantic_node_type = = semantic_node_type . wrap_def )
2017-05-20 21:20:02 +03:00
{
2017-10-23 11:21:15 +03:00
wrapped_definition_node wdn = ( wrapped_definition_node ) si . sym_info ;
si . sym_info = wdn . PCUReader . CreateInterfaceInClassMember ( wdn . offset , name ) ;
2015-05-14 22:35:07 +03:00
}
}
2017-10-23 11:21:15 +03:00
return sil ;
2015-05-14 22:35:07 +03:00
}
}
}