References, Method Emit
- loading references - COR library and Special Types - empty method body generating - method definition
This commit is contained in:
Родитель
c1312f844c
Коммит
09a22be8d1
|
@ -0,0 +1,166 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CodeGen;
|
||||
using Microsoft.CodeAnalysis.Emit;
|
||||
using Pchp.CodeAnalysis.Emit;
|
||||
using Pchp.CodeAnalysis.Symbols;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Cci = Microsoft.Cci;
|
||||
|
||||
namespace Pchp.CodeAnalysis.CodeGen
|
||||
{
|
||||
internal sealed class MethodGenerator
|
||||
{
|
||||
private static Cci.DebugSourceDocument CreateDebugDocumentForFile(string normalizedPath)
|
||||
{
|
||||
return new Cci.DebugSourceDocument(normalizedPath, Cci.DebugSourceDocument.CorSymLanguageTypeCSharp);
|
||||
}
|
||||
|
||||
internal static MethodBody GenerateMethodBody(
|
||||
PEModuleBuilder moduleBuilder,
|
||||
MethodSymbol method,
|
||||
int methodOrdinal,
|
||||
//BoundStatement block,
|
||||
//ImmutableArray<LambdaDebugInfo> lambdaDebugInfo,
|
||||
//ImmutableArray<ClosureDebugInfo> closureDebugInfo,
|
||||
//StateMachineTypeSymbol stateMachineTypeOpt,
|
||||
VariableSlotAllocator variableSlotAllocatorOpt,
|
||||
DiagnosticBag diagnostics,
|
||||
//ImportChain importChainOpt,
|
||||
bool emittingPdb)
|
||||
{
|
||||
// Note: don't call diagnostics.HasAnyErrors() in release; could be expensive if compilation has many warnings.
|
||||
Debug.Assert(!diagnostics.HasAnyErrors(), "Running code generator when errors exist might be dangerous; code generator not expecting errors");
|
||||
|
||||
var compilation = moduleBuilder.Compilation;
|
||||
var localSlotManager = new LocalSlotManager(variableSlotAllocatorOpt);
|
||||
var optimizations = compilation.Options.OptimizationLevel;
|
||||
|
||||
DebugDocumentProvider debugDocumentProvider = null;
|
||||
|
||||
if (emittingPdb)
|
||||
{
|
||||
debugDocumentProvider = (path, basePath) => moduleBuilder.GetOrAddDebugDocument(path, basePath, CreateDebugDocumentForFile);
|
||||
}
|
||||
|
||||
ILBuilder builder = new ILBuilder(moduleBuilder, localSlotManager, optimizations);
|
||||
//DiagnosticBag diagnosticsForThisMethod = DiagnosticBag.GetInstance();
|
||||
try
|
||||
{
|
||||
Cci.AsyncMethodBodyDebugInfo asyncDebugInfo = null;
|
||||
|
||||
//var codeGen = new CodeGenerator(method, block, builder, moduleBuilder, diagnosticsForThisMethod, optimizations, emittingPdb);
|
||||
|
||||
//if (diagnosticsForThisMethod.HasAnyErrors())
|
||||
//{
|
||||
// // we are done here. Since there were errors we should not emit anything.
|
||||
// return null;
|
||||
//}
|
||||
|
||||
// We need to save additional debugging information for MoveNext of an async state machine.
|
||||
//var stateMachineMethod = method as SynthesizedStateMachineMethod;
|
||||
//bool isStateMachineMoveNextMethod = stateMachineMethod != null && method.Name == WellKnownMemberNames.MoveNextMethodName;
|
||||
|
||||
//if (isStateMachineMoveNextMethod && stateMachineMethod.StateMachineType.KickoffMethod.IsAsync)
|
||||
//{
|
||||
// int asyncCatchHandlerOffset;
|
||||
// ImmutableArray<int> asyncYieldPoints;
|
||||
// ImmutableArray<int> asyncResumePoints;
|
||||
// codeGen.Generate(out asyncCatchHandlerOffset, out asyncYieldPoints, out asyncResumePoints);
|
||||
|
||||
// var kickoffMethod = stateMachineMethod.StateMachineType.KickoffMethod;
|
||||
|
||||
// // The exception handler IL offset is used by the debugger to treat exceptions caught by the marked catch block as "user unhandled".
|
||||
// // This is important for async void because async void exceptions generally result in the process being terminated,
|
||||
// // but without anything useful on the call stack. Async Task methods on the other hand return exceptions as the result of the Task.
|
||||
// // So it is undesirable to consider these exceptions "user unhandled" since there may well be user code that is awaiting the task.
|
||||
// // This is a heuristic since it's possible that there is no user code awaiting the task.
|
||||
// asyncDebugInfo = new Cci.AsyncMethodBodyDebugInfo(kickoffMethod, kickoffMethod.ReturnsVoid ? asyncCatchHandlerOffset : -1, asyncYieldPoints, asyncResumePoints);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// codeGen.Generate();
|
||||
//}
|
||||
|
||||
// DEBUG
|
||||
|
||||
builder.EmitNullConstant();
|
||||
builder.EmitRet(false);
|
||||
|
||||
builder.Realize();
|
||||
|
||||
// DEBUG
|
||||
|
||||
var localVariables = builder.LocalSlotManager.LocalsInOrder();
|
||||
|
||||
if (localVariables.Length > 0xFFFE)
|
||||
{
|
||||
//diagnosticsForThisMethod.Add(ErrorCode.ERR_TooManyLocals, method.Locations.First());
|
||||
}
|
||||
|
||||
//if (diagnosticsForThisMethod.HasAnyErrors())
|
||||
//{
|
||||
// // we are done here. Since there were errors we should not emit anything.
|
||||
// return null;
|
||||
//}
|
||||
|
||||
//// We will only save the IL builders when running tests.
|
||||
//if (moduleBuilder.SaveTestData)
|
||||
//{
|
||||
// moduleBuilder.SetMethodTestData(method, builder.GetSnapshot());
|
||||
//}
|
||||
|
||||
// Only compiler-generated MoveNext methods have iterator scopes. See if this is one.
|
||||
var stateMachineHoistedLocalScopes = default(ImmutableArray<Cci.StateMachineHoistedLocalScope>);
|
||||
//if (isStateMachineMoveNextMethod)
|
||||
//{
|
||||
// stateMachineHoistedLocalScopes = builder.GetHoistedLocalScopes();
|
||||
//}
|
||||
|
||||
var stateMachineHoistedLocalSlots = default(ImmutableArray<EncHoistedLocalInfo>);
|
||||
var stateMachineAwaiterSlots = default(ImmutableArray<Cci.ITypeReference>);
|
||||
//if (optimizations == OptimizationLevel.Debug && stateMachineTypeOpt != null)
|
||||
//{
|
||||
// Debug.Assert(method.IsAsync || method.IsIterator);
|
||||
// GetStateMachineSlotDebugInfo(moduleBuilder, moduleBuilder.GetSynthesizedFields(stateMachineTypeOpt), variableSlotAllocatorOpt, diagnosticsForThisMethod, out stateMachineHoistedLocalSlots, out stateMachineAwaiterSlots);
|
||||
// Debug.Assert(!diagnostics.HasAnyErrors());
|
||||
//}
|
||||
|
||||
return new MethodBody(
|
||||
builder.RealizedIL,
|
||||
builder.MaxStack,
|
||||
(Cci.IMethodDefinition)method.PartialDefinitionPart ?? method,
|
||||
variableSlotAllocatorOpt?.MethodId ?? new DebugId(methodOrdinal, moduleBuilder.CurrentGenerationOrdinal),
|
||||
localVariables,
|
||||
builder.RealizedSequencePoints,
|
||||
debugDocumentProvider,
|
||||
builder.RealizedExceptionHandlers,
|
||||
builder.GetAllScopes(),
|
||||
builder.HasDynamicLocal,
|
||||
null, // importScopeOpt,
|
||||
ImmutableArray<LambdaDebugInfo>.Empty, // lambdaDebugInfo,
|
||||
ImmutableArray<ClosureDebugInfo>.Empty, // closureDebugInfo,
|
||||
null, //stateMachineTypeOpt?.Name,
|
||||
stateMachineHoistedLocalScopes,
|
||||
stateMachineHoistedLocalSlots,
|
||||
stateMachineAwaiterSlots,
|
||||
asyncDebugInfo);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Basic blocks contain poolable builders for IL and sequence points. Free those back
|
||||
// to their pools.
|
||||
builder.FreeBasicBlocks();
|
||||
|
||||
//// Remember diagnostics.
|
||||
//diagnostics.AddRange(diagnosticsForThisMethod);
|
||||
//diagnosticsForThisMethod.Free();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,7 +36,8 @@ namespace Pchp.CodeAnalysis.CommandLine
|
|||
|
||||
// DEBUG
|
||||
sourceFiles.Add(new CommandLineSourceFile("test.php", false));
|
||||
//metadataReferences.Add(new CommandLineReference(@"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Collections\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Collections.dll", new MetadataReferenceProperties(MetadataImageKind.Assembly)));
|
||||
metadataReferences.Add(new CommandLineReference(@"C:\Windows\Microsoft.NET\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll", new MetadataReferenceProperties(MetadataImageKind.Assembly)));
|
||||
metadataReferences.Add(new CommandLineReference(@"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Collections\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Collections.dll", new MetadataReferenceProperties(MetadataImageKind.Assembly)));
|
||||
compilationName = "test";
|
||||
outputFileName = moduleName = "test" + outputKind.GetDefaultExtension();
|
||||
//
|
||||
|
|
|
@ -460,6 +460,14 @@ namespace Pchp.CodeAnalysis
|
|||
// Use a temporary bag so we don't have to refilter pre-existing diagnostics.
|
||||
DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance();
|
||||
|
||||
moduleBeingBuilt.SourceModule.SymbolTables.GetFunctions()
|
||||
.Concat(moduleBeingBuilt.SourceModule.SymbolTables.GetTypes().SelectMany(t => t.GetMembers().OfType<MethodSymbol>()))
|
||||
.Foreach((m) =>
|
||||
{
|
||||
var body = CodeGen.MethodGenerator.GenerateMethodBody(moduleBeingBuilt, (MethodSymbol)m, 0, null, methodBodyDiagnosticBag, false);
|
||||
moduleBeingBuilt.SetMethodBody(m, body);
|
||||
});
|
||||
|
||||
//MethodCompiler.CompileMethodBodies(
|
||||
// this,
|
||||
// moduleBeingBuilt,
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Roslyn.Utilities;
|
||||
using System.Collections.Immutable;
|
||||
using Pchp.CodeAnalysis.Symbols;
|
||||
|
||||
namespace Pchp.CodeAnalysis
|
||||
{
|
||||
partial class PhpCompilation
|
||||
{
|
||||
internal class ReferenceManager : CommonReferenceManager
|
||||
{
|
||||
internal override ImmutableArray<MetadataReference> ExplicitReferences
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray<MetadataReference>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
internal override ImmutableArray<MetadataReference> ImplicitReferences
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray<MetadataReference>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
internal override IEnumerable<KeyValuePair<AssemblyIdentity, PortableExecutableReference>> GetImplicitlyResolvedAssemblyReferences()
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
internal override MetadataReference GetMetadataReference(IAssemblySymbol assemblySymbol)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
internal override IEnumerable<KeyValuePair<MetadataReference, IAssemblySymbol>> GetReferencedAssemblies()
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
internal override IEnumerable<ValueTuple<IAssemblySymbol, ImmutableArray<string>>> GetReferencedAssemblyAliases()
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
internal void CreateSourceAssemblyForCompilation(PhpCompilation compilation)
|
||||
{
|
||||
if (compilation._lazyAssemblySymbol == null)
|
||||
{
|
||||
var assembly = new SourceAssemblySymbol(compilation, compilation.Options.ModuleName, compilation.Options.ModuleName);
|
||||
compilation._lazyAssemblySymbol = assembly;
|
||||
|
||||
assembly.SourceModule.SetReferences(new ModuleReferences<AssemblySymbol>(ImmutableArray<AssemblyIdentity>.Empty, ImmutableArray<AssemblySymbol>.Empty, ImmutableArray<UnifiedAssembly<AssemblySymbol>>.Empty), assembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,7 +68,7 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
AssemblyOrModuleSymbolToModuleRefMap.Add(sourceModule, this);
|
||||
}
|
||||
|
||||
public IModuleSymbol SourceModule => _sourceModule;
|
||||
internal SourceModuleSymbol SourceModule => _sourceModule;
|
||||
|
||||
public ArrayMethods ArrayMethods
|
||||
{
|
||||
|
@ -78,6 +78,8 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
}
|
||||
}
|
||||
|
||||
internal virtual int CurrentGenerationOrdinal => 0; // used for EditAndContinue
|
||||
|
||||
public Cci.IAssembly AsAssembly => this as Cci.IAssembly;
|
||||
|
||||
public IEnumerable<Cci.ICustomAttribute> AssemblyAttributes
|
||||
|
@ -96,6 +98,32 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
}
|
||||
}
|
||||
|
||||
internal Cci.DebugSourceDocument GetOrAddDebugDocument(string path, string basePath, Func<string, Cci.DebugSourceDocument> factory)
|
||||
{
|
||||
return _debugDocuments.GetOrAdd(NormalizeDebugDocumentPath(path, basePath), factory);
|
||||
}
|
||||
|
||||
private string NormalizeDebugDocumentPath(string path, string basePath)
|
||||
{
|
||||
//var resolver = _compilation.Options.SourceReferenceResolver;
|
||||
//if (resolver == null)
|
||||
//{
|
||||
// return path;
|
||||
//}
|
||||
|
||||
//var key = ValueTuple.Create(path, basePath);
|
||||
//string normalizedPath;
|
||||
//if (!_normalizedPathsCache.TryGetValue(key, out normalizedPath))
|
||||
//{
|
||||
// normalizedPath = resolver.NormalizePath(path, basePath) ?? path;
|
||||
// _normalizedPathsCache.TryAdd(key, normalizedPath);
|
||||
//}
|
||||
|
||||
//return normalizedPath;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public string DefaultNamespace
|
||||
{
|
||||
get
|
||||
|
@ -222,6 +250,8 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
|
||||
internal override Compilation CommonCompilation => _compilation;
|
||||
|
||||
internal PhpCompilation Compilation => _compilation;
|
||||
|
||||
internal override CommonEmbeddedTypesManager CommonEmbeddedTypesManagerOpt
|
||||
{
|
||||
get
|
||||
|
@ -610,9 +640,21 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
noPiaIndexer?.Visit((Cci.ITypeDefinition)type);
|
||||
}
|
||||
|
||||
public bool IsPlatformType(Cci.ITypeReference typeRef, Cci.PlatformType t)
|
||||
public bool IsPlatformType(Cci.ITypeReference typeRef, Cci.PlatformType platformType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var namedType = typeRef as PENamedTypeSymbol;
|
||||
if (namedType != null)
|
||||
{
|
||||
if (platformType == Cci.PlatformType.SystemType)
|
||||
{
|
||||
throw new NotImplementedException(); // below is sufficient ?
|
||||
//return (object)namedType == (object)Compilation.GetWellKnownType(WellKnownType.System_Type);
|
||||
}
|
||||
|
||||
return namedType.SpecialType == (SpecialType)platformType;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerable<Cci.IReference> ReferencesInIL(out int count)
|
||||
|
|
|
@ -49,13 +49,14 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CodeGen\MethodGenerator.cs" />
|
||||
<Compile Include="CommandLine\PhpCommandLineArguments.cs" />
|
||||
<Compile Include="CommandLine\PhpCommandLineParser.cs" />
|
||||
<Compile Include="CommandLine\PhpCompiler.cs" />
|
||||
<Compile Include="CommandLine\PhpParseOptions.cs" />
|
||||
<Compile Include="Compilation\PhpCompilation.cs" />
|
||||
<Compile Include="Compilation\PhpCompilationOptions.cs" />
|
||||
<Compile Include="Compilation\ReferenceManager.cs" />
|
||||
<Compile Include="Symbols\ReferenceManager.cs" />
|
||||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="Emitter\Model\AssemblyReference.cs" />
|
||||
<Compile Include="Emitter\Model\MethodSymbolAdapter.cs" />
|
||||
|
@ -107,7 +108,6 @@
|
|||
<ItemGroup>
|
||||
<Folder Include="Binder\" />
|
||||
<Folder Include="BoundTree\" />
|
||||
<Folder Include="CodeGen\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="PhpResources.resx">
|
||||
|
|
|
@ -34,6 +34,13 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
public virtual AssemblyIdentity Identity { get { throw new NotImplementedException(); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets COR library assembly symbol. Valid for source assembly.
|
||||
/// </summary>
|
||||
public virtual AssemblySymbol CorLibrary { get { throw new InvalidOperationException(); } }
|
||||
|
||||
public virtual bool IsCorLibrary => false;
|
||||
|
||||
public override bool IsAbstract => false;
|
||||
|
||||
public override bool IsExtern => false;
|
||||
|
|
|
@ -48,11 +48,15 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if this method is hidden if a derived type declares a method with the same name and signature.
|
||||
/// If false, any method with the same name hides this method. This flag is ignored by the runtime and is only used by compilers.
|
||||
/// </summary>
|
||||
public bool HidesBaseMethodsByName
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,10 +125,7 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public DllImportData GetDllImportData()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
public virtual DllImportData GetDllImportData() => null;
|
||||
|
||||
public ImmutableArray<AttributeData> GetReturnTypeAttributes()
|
||||
{
|
||||
|
|
|
@ -31,6 +31,11 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
/// </summary>
|
||||
readonly bool _isLinked;
|
||||
|
||||
/// <summary>
|
||||
/// Whether this assembly is the COR library.
|
||||
/// </summary>
|
||||
readonly bool _isCorLibrary;
|
||||
|
||||
/// <summary>
|
||||
/// A DocumentationProvider that provides XML documentation comments for this assembly.
|
||||
/// </summary>
|
||||
|
@ -50,6 +55,8 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
internal override ImmutableArray<byte> PublicKey => this.Identity.PublicKey;
|
||||
|
||||
public override bool IsCorLibrary => _isCorLibrary;
|
||||
|
||||
internal PEAssemblySymbol(PEAssembly assembly, DocumentationProvider documentationProvider, bool isLinked, MetadataImportOptions importOptions)
|
||||
{
|
||||
Debug.Assert(assembly != null);
|
||||
|
@ -67,11 +74,13 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
_modules = modules.AsImmutableOrNull();
|
||||
_isLinked = isLinked;
|
||||
_isCorLibrary = assembly.AssemblyReferences.Length == 0 && assembly.DeclaresTheObjectClass;
|
||||
}
|
||||
|
||||
internal static PEAssemblySymbol CreateFromFile(string path)
|
||||
internal static PEAssemblySymbol Create(PortableExecutableReference reference)
|
||||
{
|
||||
var data = AssemblyMetadata.CreateFromFile(path);
|
||||
var data = (AssemblyMetadata)reference.GetMetadata();
|
||||
//var data = AssemblyMetadata.CreateFromFile(reference.FilePath);
|
||||
var ass = data.GetAssembly();
|
||||
|
||||
return new PEAssemblySymbol(ass, DocumentationProvider.Default, true, MetadataImportOptions.Public);
|
||||
|
|
|
@ -266,11 +266,13 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
}
|
||||
}
|
||||
|
||||
TypeDefinitionHandle _handle;
|
||||
NamespaceOrTypeSymbol _container;
|
||||
TypeAttributes _flags;
|
||||
string _name;
|
||||
SpecialType _corTypeId;
|
||||
readonly TypeDefinitionHandle _handle;
|
||||
readonly NamespaceOrTypeSymbol _container;
|
||||
readonly TypeAttributes _flags;
|
||||
readonly string _name;
|
||||
string _ns;
|
||||
readonly SpecialType _corTypeId;
|
||||
|
||||
TypeKind _lazyKind;
|
||||
|
||||
private PENamedTypeSymbol(
|
||||
|
@ -292,6 +294,7 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
_handle = handle;
|
||||
_container = container;
|
||||
_ns = emittedNamespaceName;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -317,6 +320,7 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
// check if this is one of the COR library types
|
||||
if (emittedNamespaceName != null &&
|
||||
((AssemblySymbol)moduleSymbol.ContainingAssembly).IsCorLibrary &&
|
||||
//moduleSymbol.ContainingAssembly.KeepLookingForDeclaredSpecialTypes &&
|
||||
this.DeclaredAccessibility == Accessibility.Public) // NB: this.flags was set above.
|
||||
{
|
||||
|
@ -379,6 +383,10 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
public override SpecialType SpecialType => _corTypeId;
|
||||
|
||||
public override string Name => _name;
|
||||
|
||||
public override string NamespaceName => _ns;
|
||||
|
||||
internal PEModuleSymbol ContainingPEModule
|
||||
{
|
||||
get
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
}
|
||||
}
|
||||
|
||||
var typesDict = children.ToDictionary(c => c.Name);
|
||||
var typesDict = children.ToDictionary(c => MetadataHelpers.BuildQualifiedName(c.NamespaceName, c.Name));
|
||||
children.Free();
|
||||
|
||||
//if (noPiaLocalTypes != null)
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Roslyn.Utilities;
|
||||
using System.Collections.Immutable;
|
||||
using Pchp.CodeAnalysis.Symbols;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Pchp.CodeAnalysis
|
||||
{
|
||||
partial class PhpCompilation
|
||||
{
|
||||
internal class ReferenceManager : CommonReferenceManager
|
||||
{
|
||||
ImmutableArray<MetadataReference> _lazyExplicitReferences;
|
||||
ImmutableArray<MetadataReference> _lazyImplicitReferences = ImmutableArray<MetadataReference>.Empty;
|
||||
ImmutableDictionary<MetadataReference, IAssemblySymbol> _referencesMap;
|
||||
ImmutableDictionary<IAssemblySymbol, MetadataReference> _metadataMap;
|
||||
AssemblySymbol _lazyCorLibrary;
|
||||
|
||||
/// <summary>
|
||||
/// COR library containing base system types.
|
||||
/// </summary>
|
||||
internal AssemblySymbol CorLibrary => _lazyCorLibrary;
|
||||
|
||||
internal override ImmutableArray<MetadataReference> ExplicitReferences => _lazyExplicitReferences;
|
||||
|
||||
internal override ImmutableArray<MetadataReference> ImplicitReferences => _lazyImplicitReferences;
|
||||
|
||||
internal override IEnumerable<KeyValuePair<AssemblyIdentity, PortableExecutableReference>> GetImplicitlyResolvedAssemblyReferences()
|
||||
{
|
||||
foreach (var pair in _metadataMap)
|
||||
{
|
||||
var per = pair.Value as PortableExecutableReference;
|
||||
if (per != null)
|
||||
{
|
||||
yield return new KeyValuePair<AssemblyIdentity, PortableExecutableReference>(pair.Key.Identity, per);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override MetadataReference GetMetadataReference(IAssemblySymbol assemblySymbol) => _metadataMap.TryGetOrDefault(assemblySymbol);
|
||||
|
||||
internal override IEnumerable<KeyValuePair<MetadataReference, IAssemblySymbol>> GetReferencedAssemblies() => _referencesMap;
|
||||
|
||||
internal override IEnumerable<ValueTuple<IAssemblySymbol, ImmutableArray<string>>> GetReferencedAssemblyAliases()
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
internal void CreateSourceAssemblyForCompilation(PhpCompilation compilation)
|
||||
{
|
||||
if (compilation._lazyAssemblySymbol != null)
|
||||
return;
|
||||
|
||||
// TODO: lock
|
||||
|
||||
Debug.Assert(_lazyExplicitReferences.IsDefault);
|
||||
Debug.Assert(_lazyCorLibrary == null);
|
||||
|
||||
//
|
||||
var externalRefs = compilation.ExternalReferences;
|
||||
var assemblies = new List<AssemblySymbol>(externalRefs.Length);
|
||||
|
||||
var referencesMap = new Dictionary<MetadataReference, IAssemblySymbol>();
|
||||
var metadataMap = new Dictionary<IAssemblySymbol, MetadataReference>();
|
||||
|
||||
foreach (PortableExecutableReference pe in externalRefs)
|
||||
{
|
||||
var symbol = PEAssemblySymbol.Create(pe);
|
||||
if (symbol != null)
|
||||
{
|
||||
assemblies.Add(symbol);
|
||||
referencesMap[pe] = symbol;
|
||||
metadataMap[symbol] = pe;
|
||||
|
||||
if (_lazyCorLibrary == null && symbol.IsCorLibrary)
|
||||
_lazyCorLibrary = symbol;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
_lazyExplicitReferences = externalRefs;
|
||||
_lazyImplicitReferences = ImmutableArray<MetadataReference>.Empty;
|
||||
_metadataMap = metadataMap.ToImmutableDictionary();
|
||||
_referencesMap = referencesMap.ToImmutableDictionary();
|
||||
|
||||
//
|
||||
var assembly = new SourceAssemblySymbol(compilation, _lazyCorLibrary, compilation.Options.ModuleName, compilation.Options.ModuleName);
|
||||
compilation._lazyAssemblySymbol = assembly;
|
||||
|
||||
assembly.SourceModule.SetReferences(new ModuleReferences<AssemblySymbol>(
|
||||
assemblies.Select(x => x.Identity).AsImmutable(),
|
||||
assemblies.AsImmutable(),
|
||||
ImmutableArray<UnifiedAssembly<AssemblySymbol>>.Empty), assembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
{
|
||||
readonly string _simpleName;
|
||||
readonly PhpCompilation _compilation;
|
||||
readonly AssemblySymbol _corLibraryOpt;
|
||||
|
||||
/// <summary>
|
||||
/// A list of modules the assembly consists of.
|
||||
|
@ -27,6 +28,7 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
public SourceAssemblySymbol(
|
||||
PhpCompilation compilation,
|
||||
AssemblySymbol corLibraryOpt,
|
||||
string assemblySimpleName,
|
||||
string moduleName)
|
||||
{
|
||||
|
@ -36,6 +38,7 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
_compilation = compilation;
|
||||
_simpleName = assemblySimpleName;
|
||||
_corLibraryOpt = corLibraryOpt;
|
||||
|
||||
var moduleBuilder = new ArrayBuilder<IModuleSymbol>(1);
|
||||
|
||||
|
@ -54,6 +57,8 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
_modules = moduleBuilder.ToImmutableAndFree();
|
||||
}
|
||||
|
||||
public override AssemblySymbol CorLibrary => _corLibraryOpt;
|
||||
|
||||
internal SourceModuleSymbol SourceModule => (SourceModuleSymbol)_modules[0];
|
||||
|
||||
public override ImmutableArray<IModuleSymbol> Modules => _modules;
|
||||
|
|
|
@ -30,6 +30,10 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
public override Symbol ContainingSymbol => _compilation.SourceModule;
|
||||
|
||||
internal override IModuleSymbol ContainingModule => _compilation.SourceModule;
|
||||
|
||||
public override IAssemblySymbol ContainingAssembly => _compilation.SourceAssembly;
|
||||
|
||||
public override Accessibility DeclaredAccessibility => Accessibility.Public;
|
||||
|
||||
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
|
||||
|
|
|
@ -14,11 +14,11 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
/// </summary>
|
||||
internal sealed class SourceMethodSymbol : MethodSymbol
|
||||
{
|
||||
readonly NamedTypeSymbol _type;
|
||||
readonly SourceNamedTypeSymbol _type;
|
||||
readonly MethodDecl/*!*/_syntax;
|
||||
readonly ImmutableArray<ParameterSymbol> _params;
|
||||
|
||||
public SourceMethodSymbol(NamedTypeSymbol/*!*/type, MethodDecl/*!*/syntax)
|
||||
public SourceMethodSymbol(SourceNamedTypeSymbol/*!*/type, MethodDecl/*!*/syntax)
|
||||
{
|
||||
Contract.ThrowIfNull(type);
|
||||
Contract.ThrowIfNull(syntax);
|
||||
|
@ -38,6 +38,8 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
}
|
||||
}
|
||||
|
||||
public override string Name => _syntax.Name.Value;
|
||||
|
||||
public override Symbol ContainingSymbol => _type;
|
||||
|
||||
public override Accessibility DeclaredAccessibility => _syntax.Modifiers.GetAccessibility();
|
||||
|
@ -102,7 +104,10 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var objtype = _type.DeclaringCompilation.SourceAssembly.CorLibrary.Modules[0].GlobalNamespace.GetTypeMembers("System.Object");
|
||||
|
||||
//throw new NotImplementedException();
|
||||
return objtype[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче