internal SourceAssemblySymbol CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                {
                    return(compilation._lazyAssemblySymbol);
                }

                var resolver   = compilation.Options.MetadataReferenceResolver;
                var moduleName = compilation.MakeSourceModuleName();

                var assemblies = new List <AssemblySymbol>();

                if (_lazyExplicitReferences.IsDefault)
                {
                    //
                    var externalRefs  = compilation.ExternalReferences;
                    var referencesMap = new Dictionary <MetadataReference, IAssemblySymbolInternal>();
                    var metadataMap   = new Dictionary <IAssemblySymbol, MetadataReference>();
                    var assembliesMap = new Dictionary <AssemblyIdentity, PEAssemblySymbol>();
                    var observed      = new HashSet <AssemblyIdentity>();

                    foreach (PortableExecutableReference pe in externalRefs)
                    {
                        var peass = ((AssemblyMetadata)pe.GetMetadata()).GetAssembly();

                        if (!observed.Add(peass.Identity))
                        {
                            // already added reference identity, different metadata
                            referencesMap[pe] = _observedMetadata[peass.Identity];
                            Debug.Assert(referencesMap[pe] != null);
                            continue;
                        }

                        var symbol = _observedMetadata.TryGetOrDefault(peass.Identity) ?? PEAssemblySymbol.Create(pe, peass, isLinked: true);
                        if (symbol != null)
                        {
                            assemblies.Add(symbol);
                            referencesMap[pe]   = symbol;
                            metadataMap[symbol] = pe;

                            if (_lazyCorLibrary == null && symbol.IsCorLibrary)
                            {
                                _lazyCorLibrary = symbol;
                            }

                            if (_lazyPhpCorLibrary == null && symbol.IsPeachpieCorLibrary)
                            {
                                _lazyPhpCorLibrary = symbol;
                            }

                            // cache bound assembly symbol
                            _observedMetadata[symbol.Identity] = symbol;
                        }
                        else
                        {
                            _diagnostics.Add(Location.None, Errors.ErrorCode.ERR_MetadataFileNotFound, peass.Identity);
                        }
                    }

                    // list of modules to initialize later
                    var refmodules = assemblies.SelectMany(symbol => symbol.Modules.Cast <PEModuleSymbol>()).ToList();

                    //
                    _lazyExplicitReferences = externalRefs;
                    _lazyImplicitReferences = ImmutableArray <MetadataReference> .Empty;
                    _metadataMap            = metadataMap.ToImmutableDictionary();
                    _referencesMap          = referencesMap.ToImmutableDictionary();

                    //
                    assemblies.ForEach(ass => ass.SetCorLibrary(_lazyCorLibrary));

                    // recursively initialize references of referenced modules
                    SetReferencesOfReferencedModules(resolver, refmodules);
                }
                else
                {
                    foreach (PortableExecutableReference pe in _lazyExplicitReferences)
                    {
                        var ass = (AssemblySymbol)_referencesMap[pe];
                        Debug.Assert(ass != null);
                        assemblies.Add(ass);
                    }
                }

                //
                var assembly = new SourceAssemblySymbol(compilation, this.SimpleAssemblyName, moduleName);

                assembly.SetCorLibrary(_lazyCorLibrary);
                assembly.SourceModule.SetReferences(new ModuleReferences <AssemblySymbol>(
                                                        assemblies.Select(x => x.Identity).AsImmutable(),
                                                        assemblies.AsImmutable(),
                                                        ImmutableArray <UnifiedAssembly <AssemblySymbol> > .Empty), assembly);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null)
                {
                    _diagnostics.Add(Location.None, Errors.ErrorCode.ERR_MetadataFileNotFound, "Peachpie.Runtime.dll");
                    throw new DllNotFoundException("Peachpie.Runtime not found");
                }
                if (_lazyCorLibrary == null)
                {
                    throw new DllNotFoundException("A corlib not found");
                }

                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);

                //
                return(assembly);
            }
示例#2
0
            internal SourceAssemblySymbol CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                {
                    return(compilation._lazyAssemblySymbol);
                }

                var resolver   = compilation.Options.MetadataReferenceResolver;
                var moduleName = compilation.MakeSourceModuleName();

                var assemblies = new List <AssemblySymbol>();

                if (_lazyExplicitReferences.IsDefault)
                {
                    //
                    var externalRefs = compilation.ExternalReferences;
                    var refmodules   = new List <PEModuleSymbol>();

                    var referencesMap = new Dictionary <MetadataReference, IAssemblySymbol>();
                    var metadataMap   = new Dictionary <IAssemblySymbol, MetadataReference>();
                    var assembliesMap = new Dictionary <AssemblyIdentity, PEAssemblySymbol>();

                    foreach (PortableExecutableReference pe in externalRefs)
                    {
                        var peass = ((AssemblyMetadata)pe.GetMetadata()).GetAssembly();

                        var symbol = _observedMetadata.TryGetOrDefault(peass.Identity) ?? PEAssemblySymbol.Create(pe, peass);
                        if (symbol != null)
                        {
                            assemblies.Add(symbol);
                            referencesMap[pe]   = symbol;
                            metadataMap[symbol] = pe;

                            if (_lazyCorLibrary == null && symbol.IsCorLibrary)
                            {
                                _lazyCorLibrary = symbol;
                            }

                            if (_lazyPhpCorLibrary == null && symbol.IsPchpCorLibrary)
                            {
                                _lazyPhpCorLibrary = symbol;
                            }

                            // cache bound assembly symbol
                            _observedMetadata[symbol.Identity] = symbol;

                            // list of modules to initialize later
                            refmodules.AddRange(symbol.Modules.Cast <PEModuleSymbol>());
                        }
                        else
                        {
                            throw new Exception($"symbol '{pe.FilePath}' could not be created!");
                        }
                    }

                    //
                    _lazyExplicitReferences = externalRefs;
                    _lazyImplicitReferences = ImmutableArray <MetadataReference> .Empty;
                    _metadataMap            = metadataMap.ToImmutableDictionary();
                    _referencesMap          = referencesMap.ToImmutableDictionary();

                    //
                    assemblies.ForEach(ass => ass.SetCorLibrary(_lazyCorLibrary));

                    // recursively initialize references of referenced modules
                    SetReferencesOfReferencedModules(resolver, refmodules);
                }
                else
                {
                    foreach (PortableExecutableReference pe in _lazyExplicitReferences)
                    {
                        var ass = (AssemblySymbol)_referencesMap[pe];
                        Debug.Assert(ass != null);
                        assemblies.Add(ass);
                    }
                }

                //
                var assembly = new SourceAssemblySymbol(compilation, this.SimpleAssemblyName, moduleName);

                assembly.SetCorLibrary(_lazyCorLibrary);
                assembly.SourceModule.SetReferences(new ModuleReferences <AssemblySymbol>(
                                                        assemblies.Select(x => x.Identity).AsImmutable(),
                                                        assemblies.AsImmutable(),
                                                        ImmutableArray <UnifiedAssembly <AssemblySymbol> > .Empty), assembly);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null)
                {
                    throw new DllNotFoundException("Peachpie.Runtime not found");
                }
                if (_lazyCorLibrary == null)
                {
                    throw new DllNotFoundException("A corlib not found");
                }

                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);

                //
                return(assembly);
            }