示例#1
0
        /// <summary>
        /// </summary>
        /// <param name="assemblyMetadata">
        /// </param>
        /// <returns>
        /// </returns>
        private AssemblySymbol LoadAssemblySymbol(AssemblyMetadata assemblyMetadata, bool noCache = false)
        {
            AssemblySymbol symbol;

            if (!noCache && this.cache.TryGetValue(assemblyMetadata.Assembly.Identity, out symbol))
            {
                return(symbol);
            }

            var assemblySymbol = new PEAssemblySymbol(assemblyMetadata.Assembly, DocumentationProvider.Default, isLinked: false, importOptions: MetadataImportOptions.All);

            this.cache[assemblyMetadata.Assembly.Identity] = assemblySymbol;
            this.unifiedAssemblies.Add(new UnifiedAssembly <AssemblySymbol>(assemblySymbol, assemblyMetadata.Assembly.Identity));

            var moduleReferences = this.LoadReferences(assemblyMetadata);

            foreach (var module in assemblySymbol.Modules)
            {
                module.SetReferences(moduleReferences);
            }

            this.SetCorLib(assemblySymbol);

            return(assemblySymbol);
        }
示例#2
0
 private void AppendAssemblyRefs(StringBuilder result, PEAssemblySymbol assembly)
 {
     foreach (var a in assembly.PrimaryModule.GetReferencedAssemblies())
     {
         result.Append(".assembly extern ");
         result.AppendLine(a.GetDisplayName(fullKey: true));
     }
 }
示例#3
0
 public CSharpSymbolMatcher(
     IReadOnlyDictionary<AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap,
     SourceAssemblySymbol sourceAssembly,
     EmitContext sourceContext,
     PEAssemblySymbol otherAssembly)
 {
     this.defs = new MatchDefsToMetadata(sourceContext, otherAssembly);
     this.symbols = new MatchSymbols(anonymousTypeMap, sourceAssembly, otherAssembly);
 }
示例#4
0
        public CSharpSymbolMatcher(
            IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap,
            SourceAssemblySymbol sourceAssembly,
            EmitContext sourceContext,
            PEAssemblySymbol otherAssembly)
        {
            _defs = new MatchDefsToMetadata(sourceContext, otherAssembly);

            _symbols = new MatchSymbols(
                anonymousTypeMap,
                sourceAssembly,
                otherAssembly,
                otherSynthesizedMembersOpt: null);
        }
示例#5
0
        /// <summary>
        /// </summary>
        /// <param name="assemblySymbol">
        /// </param>
        private void SetCorLib(PEAssemblySymbol assemblySymbol)
        {
            if (!assemblySymbol.Assembly.AssemblyReferences.Any())
            {
                // this is the core lib
                assemblySymbol.SetCorLibrary(assemblySymbol);
                return;
            }

            if (this.SetCorLib(assemblySymbol, assemblySymbol))
            {
                return;
            }

            Debug.Fail("CoreLib not set");
        }
            AssemblySymbol CreateAssemblyFromIdentity(MetadataReferenceResolver resolver, AssemblyIdentity identity, string basePath, List <PEModuleSymbol> modules)
            {
                if (!_observedMetadata.TryGetValue(identity, out var ass))
                {
                    // temporary: lookup ignoring version number
                    foreach (var pair in _observedMetadata)
                    {
                        if (IsIdentitySimilar(pair.Key, identity))
                        {
                            _observedMetadata[identity] = pair.Value;   // do not resolve this ever again
                            return(pair.Value);
                        }
                    }

                    //foreach (var m in modules)
                    //{
                    //    if (IsIdentitySimilar(m.ContainingAssembly.Identity, identity))
                    //    {
                    //        return m.ContainingAssembly as PEAssemblySymbol;
                    //    }
                    //}

                    //
                    if (resolver != null)
                    {
                        string keytoken = string.Join("", identity.PublicKeyToken.Select(b => b.ToString("x2")));
                        var    pes      = resolver.ResolveReference(identity.Name + ".dll", basePath, MetadataReferenceProperties.Assembly)
                                          .Concat(resolver.ResolveReference($"{identity.Name}/v4.0_{identity.Version}__{keytoken}/{identity.Name}.dll", basePath, MetadataReferenceProperties.Assembly));

                        var pe = pes.FirstOrDefault();
                        if (pe != null)
                        {
                            _observedMetadata[identity] = ass = PEAssemblySymbol.Create(pe, isLinked: false);
                            ass.SetCorLibrary(_lazyCorLibrary);
                            modules.AddRange(ass.Modules.Cast <PEModuleSymbol>());
                        }
                    }

                    if (ass == null)
                    {
                        //_diagnostics.Add(Location.None, Errors.ErrorCode.ERR_MetadataFileNotFound, identity);
                        return(new MissingAssemblySymbol(identity));
                    }
                }

                return(ass);
            }
示例#7
0
        public CSharpSymbolMatcher(
            IReadOnlyDictionary <AnonymousTypeKey, AnonymousTypeValue> anonymousTypeMap,
            IReadOnlyDictionary <SynthesizedDelegateKey, SynthesizedDelegateValue> synthesizedDelegates,
            SourceAssemblySymbol sourceAssembly,
            EmitContext sourceContext,
            PEAssemblySymbol otherAssembly)
        {
            _defs = new MatchDefsToMetadata(sourceContext, otherAssembly);

            _symbols = new MatchSymbols(
                anonymousTypeMap,
                synthesizedDelegates,
                sourceAssembly,
                otherAssembly,
                otherSynthesizedMembers: null,
                deepTranslator: null);
        }
            AssemblySymbol CreateAssemblyFromIdentity(MetadataReferenceResolver resolver, AssemblyIdentity identity, string basePath, List <PEModuleSymbol> modules)
            {
                PEAssemblySymbol ass;

                if (!_observedMetadata.TryGetValue(identity, out ass))
                {
                    // temporary: lookup ignoring minor version number
                    foreach (var pair in _observedMetadata)
                    {
                        // TODO: _identityComparer
                        if (pair.Key.Name.Equals(identity.Name, StringComparison.OrdinalIgnoreCase) &&
                            (pair.Key.Version.Major == identity.Version.Major || identity.Version == new Version(0, 0, 0, 0)))
                        {
                            _observedMetadata[identity] = pair.Value;
                            return(pair.Value);
                        }
                    }

                    //
                    if (resolver != null)
                    {
                        string keytoken = string.Join("", identity.PublicKeyToken.Select(b => b.ToString("x2")));
                        var    pes      = resolver.ResolveReference(identity.Name + ".dll", basePath, MetadataReferenceProperties.Assembly)
                                          .Concat(resolver.ResolveReference($"{identity.Name}/v4.0_{identity.Version}__{keytoken}/{identity.Name}.dll", basePath, MetadataReferenceProperties.Assembly));

                        var pe = pes.FirstOrDefault();
                        if (pe != null)
                        {
                            _observedMetadata[identity] = ass = PEAssemblySymbol.Create(pe, isLinked: false);
                            ass.SetCorLibrary(_lazyCorLibrary);
                            modules.AddRange(ass.Modules.Cast <PEModuleSymbol>());
                        }
                    }

                    if (ass == null)
                    {
                        //_diagnostics.Add(Location.None, Errors.ErrorCode.ERR_MetadataFileNotFound, identity);
                        return(new MissingAssemblySymbol(identity));
                    }
                }

                return(ass);
            }
示例#9
0
            PEAssemblySymbol CreateAssemblyFromIdentity(MetadataReferenceResolver resolver, AssemblyIdentity identity, string basePath, List <PEModuleSymbol> modules)
            {
                PEAssemblySymbol ass;

                if (!_observedMetadata.TryGetValue(identity, out ass))
                {
                    // temporary: lookup ignoring minor version number
                    foreach (var pair in _observedMetadata)
                    {
                        // TODO: _identityComparer
                        if (pair.Key.Name.Equals(identity.Name, StringComparison.OrdinalIgnoreCase) && pair.Key.Version.Major == identity.Version.Major)
                        {
                            _observedMetadata[identity] = pair.Value;
                            return(pair.Value);
                        }
                    }

                    //
                    string keytoken = string.Join("", identity.PublicKeyToken.Select(b => b.ToString("x2")));
                    var    pes      = resolver.ResolveReference(identity.Name + ".dll", basePath, MetadataReferenceProperties.Assembly)
                                      .Concat(resolver.ResolveReference($"{identity.Name}/v4.0_{identity.Version}__{keytoken}/{identity.Name}.dll", basePath, MetadataReferenceProperties.Assembly));

                    var pe = pes.FirstOrDefault();
                    if (pe != null)
                    {
                        _observedMetadata[identity] = ass = PEAssemblySymbol.Create(pe);
                        ass.SetCorLibrary(_lazyCorLibrary);
                        modules.AddRange(ass.Modules.Cast <PEModuleSymbol>());
                    }
                    else
                    {
                        // TODO: diagnostics
                        throw new DllNotFoundException(identity.GetDisplayName());
                    }
                }

                return(ass);
            }
示例#10
0
        private bool SetCorLib(PEAssemblySymbol assemblySymbol, PEAssemblySymbol fromAssemblySymbol)
        {
            var loadedRefAssemblies = from assemblyIdentity in fromAssemblySymbol.Assembly.AssemblyReferences select this.LoadAssemblySymbol(assemblyIdentity);

            foreach (var loadedRefAssemblySymbol in loadedRefAssemblies)
            {
                var peRefAssembly = loadedRefAssemblySymbol as PEAssemblySymbol;
                if (peRefAssembly != null && !peRefAssembly.Assembly.AssemblyReferences.Any())
                {
                    assemblySymbol.SetCorLibrary(loadedRefAssemblySymbol);
                    return(true);
                }
            }

            foreach (var loadedRefAssemblySymbol in loadedRefAssemblies)
            {
                if (this.SetCorLib(assemblySymbol, loadedRefAssemblySymbol as PEAssemblySymbol))
                {
                    return(true);
                }
            }

            return(false);
        }
            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);
            }
示例#12
0
 public MatchDefsToMetadata(EmitContext sourceContext, PEAssemblySymbol otherAssembly) :
     base(sourceContext)
 {
     _otherAssembly = otherAssembly;
 }
示例#13
0
            internal void CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                {
                    return;
                }

                // TODO: lock

                Debug.Assert(_lazyExplicitReferences.IsDefault);
                Debug.Assert(_lazyCorLibrary == null);
                Debug.Assert(_lazyPhpCorLibrary == null);

                //
                var externalRefs = CorLibReferences.SelectMany(reference => compilation.Options.MetadataReferenceResolver.ResolveReference(reference, null, new MetadataReferenceProperties()))
                                   .Concat(compilation.ExternalReferences).AsImmutable();
                var assemblies = new List <AssemblySymbol>(externalRefs.Length);

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

                var refmodules = new List <PEModuleSymbol>();

                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;
                        }

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

                        // cache bound assembly symbol
                        _assembliesMap.Add(symbol.Identity, symbol);

                        // list of modules to initialize later
                        refmodules.AddRange(symbol.Modules.Cast <PEModuleSymbol>());
                    }
                }

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

                //
                var assembly = new SourceAssemblySymbol(compilation, compilation.Options.ModuleName, compilation.Options.ModuleName);

                assembly.SetCorLibrary(_lazyCorLibrary);
                compilation._lazyAssemblySymbol = assembly;

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

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

                // recursively initialize references of referenced modules
                SetReferencesOfReferencedModules(compilation.Options.MetadataReferenceResolver, refmodules);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null)
                {
                    throw new DllNotFoundException("pchpcor.dll not found");
                }
                if (_lazyCorLibrary == null)
                {
                    throw new DllNotFoundException("corlib not found");
                }
                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);
            }
示例#14
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);
            }