@ -17,16 +17,42 @@ using Mono.CompilerServices.SymbolWriter;
@@ -17,16 +17,42 @@ using Mono.CompilerServices.SymbolWriter;
using System.Diagnostics ;
using System.Linq ;
namespace Mono.CSharp {
/// <summary>
/// This is one single source file.
/// </summary>
/// <remarks>
/// This is intentionally a class and not a struct since we need
/// to pass this by reference.
/// </remarks>
public class SourceFile : ISourceFile , IEquatable < SourceFile >
namespace Mono.CSharp
{
//
// This is one single source file.
//
public class SourceFile : IEquatable < SourceFile >
{
//
// Used by #line directive to track hidden sequence point
// regions
//
struct LocationRegion : IComparable < LocationRegion >
{
public readonly Location Start ;
public readonly Location End ;
public LocationRegion ( Location start , Location end )
{
this . Start = start ;
this . End = end ;
}
public int CompareTo ( LocationRegion other )
{
if ( Start . Row = = other . Start . Row )
return Start . Column . CompareTo ( other . Start . Column ) ;
return Start . Row . CompareTo ( other . Start . Row ) ;
}
public override string ToString ( )
{
return Start . ToString ( ) + " - " + End . ToString ( ) ;
}
}
public readonly string Name ;
public readonly string FullPathName ;
public readonly int Index ;
@ -34,6 +60,7 @@ namespace Mono.CSharp {
@@ -34,6 +60,7 @@ namespace Mono.CSharp {
SourceFileEntry file ;
byte [ ] guid , checksum ;
List < LocationRegion > hidden_lines ;
public SourceFile ( string name , string path , int index )
{
@ -43,11 +70,9 @@ namespace Mono.CSharp {
@@ -43,11 +70,9 @@ namespace Mono.CSharp {
}
public SourceFileEntry SourceFileEntry {
get { return file ; }
}
SourceFileEntry ISourceFile . Entry {
get { return file ; }
get {
return file ;
}
}
public void SetChecksum ( byte [ ] guid , byte [ ] checksum )
@ -56,8 +81,11 @@ namespace Mono.CSharp {
@@ -56,8 +81,11 @@ namespace Mono.CSharp {
this . checksum = checksum ;
}
public virtual void Defin eSymbolInfo ( MonoSymbolWriter symwriter )
public SourceFileEntry Creat eSymbolInfo ( MonoSymbolWriter symwriter )
{
if ( hidden_lines ! = null )
hidden_lines . Sort ( ) ;
if ( guid ! = null )
file = symwriter . DefineDocument ( FullPathName , guid , checksum ) ;
else {
@ -65,6 +93,8 @@ namespace Mono.CSharp {
@@ -65,6 +93,8 @@ namespace Mono.CSharp {
if ( AutoGenerated )
file . SetAutoGenerated ( ) ;
}
return file ;
}
public bool Equals ( SourceFile other )
@ -72,97 +102,33 @@ namespace Mono.CSharp {
@@ -72,97 +102,33 @@ namespace Mono.CSharp {
return FullPathName = = other . FullPathName ;
}
public override string ToString ( )
{
return String . Format ( "SourceFile ({0}:{1}:{2}:{3})" ,
Name , FullPathName , Index , SourceFileEntry ) ;
}
}
public class CompilationSourceFile : SourceFile , ICompileUnit
{
CompileUnitEntry comp_unit ;
Dictionary < string , SourceFile > include_files ;
Dictionary < string , bool > conditionals ;
NamespaceContainer ns_container ;
public CompilationSourceFile ( string name , string fullPathName , int index )
: base ( name , fullPathName , index )
public bool IsHiddenLocation ( Location loc )
{
}
if ( hidden_lines = = null )
return false ;
CompileUnitEntry ICompileUnit . Entry {
get { return comp_unit ; }
}
public CompileUnitEntry CompileUnitEntry {
get { return comp_unit ; }
}
public NamespaceContainer NamespaceContainer {
get {
return ns_container ;
int index = hidden_lines . BinarySearch ( new LocationRegion ( loc , loc ) ) ;
index = ~ index ;
if ( index > 0 ) {
var found = hidden_lines [ index - 1 ] ;
if ( loc . Row < found . End . Row )
return true ;
}
set {
ns_container = value ;
}
}
public void AddIncludeFile ( SourceFile file )
{
if ( file = = this )
return ;
if ( include_files = = null )
include_files = new Dictionary < string , SourceFile > ( ) ;
if ( ! include_files . ContainsKey ( file . FullPathName ) )
include_files . Add ( file . FullPathName , file ) ;
}
public void AddDefine ( string value )
{
if ( conditionals = = null )
conditionals = new Dictionary < string , bool > ( 2 ) ;
conditionals [ value ] = tru e;
return false ;
}
public void AddUndefine ( string value )
public void RegisterHiddenScope ( Location start , Location end )
{
if ( conditional s = = null )
conditionals = new Dictionary < string , bool > ( 2 ) ;
if ( hidden_lines = = null )
hidden_lines = new List < LocationRegion > ( ) ;
conditionals [ value ] = false ;
hidden_lines . Add ( new LocationRegion ( start , end ) ) ;
}
public override void DefineSymbolInfo ( MonoSymbolWriter symwriter )
{
base . DefineSymbolInfo ( symwriter ) ;
comp_unit = symwriter . DefineCompilationUnit ( SourceFileEntry ) ;
if ( include_files ! = null ) {
foreach ( SourceFile include in include_files . Values ) {
include . DefineSymbolInfo ( symwriter ) ;
comp_unit . AddFile ( include . SourceFileEntry ) ;
}
}
}
public bool IsConditionalDefined ( CompilerContext ctx , string value )
public override string ToString ( )
{
if ( conditionals ! = null ) {
bool res ;
if ( conditionals . TryGetValue ( value , out res ) )
return res ;
// When conditional was undefined
if ( conditionals . ContainsKey ( value ) )
return false ;
}
return ctx . Settings . IsConditionalSymbolDefined ( value ) ;
return String . Format ( "SourceFile ({0}:{1}:{2})" , Name , FullPathName , Index ) ;
}
}
@ -186,37 +152,33 @@ namespace Mono.CSharp {
@@ -186,37 +152,33 @@ namespace Mono.CSharp {
{
struct Checkpoint {
public readonly int LineOffset ;
public readonly int CompilationUnit ;
public readonly int File ;
public Checkpoint ( int compile_unit , int file , int line )
public Checkpoint ( int file , int line )
{
File = file ;
CompilationUnit = compile_unit ;
LineOffset = line - ( int ) ( line % ( 1 < < line_delta_bits ) ) ;
}
}
#if FULL_AST
long token ;
readonly long token ;
const int column_bits = 2 4 ;
const int line_delta_bits = 2 4 ;
#else
int token ;
readonly int token ;
const int column_bits = 8 ;
const int line_delta_bits = 8 ;
#endif
const int checkpoint_bits = 1 6 ;
// -2 because the last one is used for hidden
const int max_column = ( 1 < < column_bits ) - 2 ;
const int column_mask = ( 1 < < column_bits ) - 1 ;
const int max_column = column_mask ;
static List < SourceFile > source_list ;
static int current_source ;
static int current_compile_unit ;
static Checkpoint [ ] checkpoints ;
static int checkpoint_index ;
@ -232,15 +194,12 @@ namespace Mono.CSharp {
@@ -232,15 +194,12 @@ namespace Mono.CSharp {
{
source_list = new List < SourceFile > ( ) ;
current_source = 0 ;
current_compile_unit = 0 ;
checkpoint_index = 0 ;
}
public static SourceFile AddFile ( string name , string fullNam e)
public static void AddFile ( SourceFile fil e)
{
var source = new SourceFile ( name , fullName , source_list . Count + 1 ) ;
source_list . Add ( source ) ;
return source ;
source_list . Add ( file ) ;
}
// <summary>
@ -249,7 +208,7 @@ namespace Mono.CSharp {
@@ -249,7 +208,7 @@ namespace Mono.CSharp {
// source file. We reserve some extra space for files we encounter via #line
// directives while parsing.
// </summary>
static public void Initialize ( List < Compilation SourceFile> files )
static public void Initialize ( List < SourceFile > files )
{
#if NET_4_0
source_list . AddRange ( files ) ;
@ -257,15 +216,14 @@ namespace Mono.CSharp {
@@ -257,15 +216,14 @@ namespace Mono.CSharp {
source_list . AddRange ( files . ToArray ( ) ) ;
#endif
checkpoints = new Checkpoint [ source_list . Count * 2 ] ;
checkpoints = new Checkpoint [ System . Math . Max ( 1 , source_list . Count * 2 ) ] ;
if ( checkpoints . Length > 0 )
checkpoints [ 0 ] = new Checkpoint ( 0 , 0 , 0 ) ;
checkpoints [ 0 ] = new Checkpoint ( 0 , 0 ) ;
}
static public void Push ( CompilationSourceFile compile_unit , SourceFile file )
static public void Push ( SourceFile file )
{
current_source = file ! = null ? file . Index : - 1 ;
current_compile_unit = compile_unit ! = null ? compile_unit . Index : - 1 ;
// File is always pushed before being changed.
}
@ -276,8 +234,6 @@ namespace Mono.CSharp {
@@ -276,8 +234,6 @@ namespace Mono.CSharp {
else {
if ( column > max_column )
column = max_column ;
else if ( column < 0 )
column = max_column + 1 ;
long target = - 1 ;
long delta = 0 ;
@ -296,7 +252,7 @@ namespace Mono.CSharp {
@@ -296,7 +252,7 @@ namespace Mono.CSharp {
}
}
if ( target = = - 1 ) {
AddCheckpoint ( current_compile_unit , current_ source , row ) ;
AddCheckpoint ( current_source , row ) ;
target = checkpoint_index ;
delta = row % ( 1 < < line_delta_bits ) ;
}
@ -317,12 +273,12 @@ namespace Mono.CSharp {
@@ -317,12 +273,12 @@ namespace Mono.CSharp {
return new Location ( loc . Row , loc . Column - columns ) ;
}
static void AddCheckpoint ( int compile_unit , int file , int row )
static void AddCheckpoint ( int file , int row )
{
if ( checkpoints . Length = = + + checkpoint_index ) {
Array . Resize ( ref checkpoints , checkpoint_index * 2 ) ;
}
checkpoints [ checkpoint_index ] = new Checkpoint ( compile_unit , file , row ) ;
checkpoints [ checkpoint_index ] = new Checkpoint ( file , row ) ;
}
string FormatLocation ( string fileName )
@ -354,10 +310,9 @@ namespace Mono.CSharp {
@@ -354,10 +310,9 @@ namespace Mono.CSharp {
public string Name {
get {
int index = File ;
if ( token = = 0 | | index = = 0 )
return "Internal" ;
if ( source_list = = null | | index - 1 > = source_list . Count )
return "unknown_file" ;
if ( token = = 0 | | index < = 0 )
return null ;
SourceFile file = source_list [ index - 1 ] ;
return file . Name ;
@ -367,8 +322,8 @@ namespace Mono.CSharp {
@@ -367,8 +322,8 @@ namespace Mono.CSharp {
public string NameFullPath {
get {
int index = File ;
if ( token = = 0 | | index = = 0 )
return "Internal" ;
if ( token = = 0 | | index < = 0 )
return null ;
return source_list [ index - 1 ] . FullPathName ;
}
@ -397,23 +352,7 @@ namespace Mono.CSharp {
@@ -397,23 +352,7 @@ namespace Mono.CSharp {
get {
if ( token = = 0 )
return 1 ;
int col = ( int ) ( token & column_mask ) ;
return col > max_column ? 1 : col ;
}
}
public bool Hidden {
get {
return ( int ) ( token & column_mask ) = = max_column + 1 ;
}
}
public int CompilationUnitIndex {
get {
if ( token = = 0 )
return 0 ;
if ( checkpoints . Length < = CheckpointIndex ) throw new Exception ( String . Format ( "Should not happen. Token is {0:X04}, checkpoints are {1}, index is {2}" , token , checkpoints . Length , CheckpointIndex ) ) ;
return checkpoints [ CheckpointIndex ] . CompilationUnit ;
return ( int ) ( token & column_mask ) ;
}
}
@ -443,16 +382,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
@@ -443,16 +382,7 @@ if (checkpoints.Length <= CheckpointIndex) throw new Exception (String.Format ("
int index = File ;
if ( index = = 0 )
return null ;
return ( SourceFile ) source_list [ index - 1 ] ;
}
}
public CompilationSourceFile CompilationUnit {
get {
int index = CompilationUnitIndex ;
if ( index = = 0 )
return null ;
return ( CompilationSourceFile ) source_list [ index - 1 ] ;
return source_list [ index - 1 ] ;
}
}