SourceNamedTypeSymbol
- NamedTypeSymbol - TypeSymbol - NamespaceSymbol - SourceModuleSymbol - temporary use of SourceUnit
This commit is contained in:
Родитель
f382876b3f
Коммит
4f2fa1fd56
|
@ -196,11 +196,10 @@ namespace Pchp.CodeAnalysis
|
|||
options,
|
||||
ValidateReferences<CompilationReference>(references));
|
||||
|
||||
// TODO: AddSyntaxTrees(syntaxTrees)
|
||||
//if (syntaxTrees != null)
|
||||
//{
|
||||
// compilation = compilation.AddSyntaxTrees(syntaxTrees);
|
||||
//}
|
||||
if (syntaxTrees != null)
|
||||
{
|
||||
compilation = compilation.AddSyntaxTrees(syntaxTrees);
|
||||
}
|
||||
|
||||
return compilation;
|
||||
}
|
||||
|
@ -322,6 +321,14 @@ namespace Pchp.CodeAnalysis
|
|||
);
|
||||
}
|
||||
|
||||
internal ImmutableArray<SourceUnit> _syntaxtreestmp;
|
||||
|
||||
public PhpCompilation AddSyntaxTrees(IEnumerable<SourceUnit> syntaxTrees)
|
||||
{
|
||||
_syntaxtreestmp = syntaxTrees.AsImmutable();
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override Compilation CommonAddSyntaxTrees(IEnumerable<SyntaxTree> trees)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
|
|
@ -0,0 +1,876 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.CodeAnalysis.Emit;
|
||||
using Roslyn.Utilities;
|
||||
using Cci = Microsoft.Cci;
|
||||
using Pchp.CodeAnalysis.Emit;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace Pchp.CodeAnalysis.Symbols
|
||||
{
|
||||
internal partial class NamedTypeSymbol :
|
||||
Cci.ITypeReference,
|
||||
Cci.ITypeDefinition,
|
||||
Cci.INamedTypeReference,
|
||||
Cci.INamedTypeDefinition,
|
||||
Cci.INamespaceTypeReference,
|
||||
Cci.INamespaceTypeDefinition,
|
||||
Cci.INestedTypeReference,
|
||||
Cci.INestedTypeDefinition,
|
||||
Cci.IGenericTypeInstanceReference,
|
||||
Cci.ISpecializedNestedTypeReference
|
||||
{
|
||||
bool Cci.ITypeReference.IsEnum
|
||||
{
|
||||
get { return this.TypeKind == TypeKind.Enum; }
|
||||
}
|
||||
|
||||
bool Cci.ITypeReference.IsValueType
|
||||
{
|
||||
get { return this.IsValueType; }
|
||||
}
|
||||
|
||||
Cci.ITypeDefinition Cci.ITypeReference.GetResolvedType(EmitContext context)
|
||||
{
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
return AsTypeDefinitionImpl(moduleBeingBuilt);
|
||||
}
|
||||
|
||||
Cci.PrimitiveTypeCode Cci.ITypeReference.TypeCode(EmitContext context)
|
||||
{
|
||||
Debug.Assert(this.IsDefinitionOrDistinct());
|
||||
|
||||
//if (this.IsDefinition)
|
||||
//{
|
||||
// return this.PrimitiveTypeCode;
|
||||
//}
|
||||
|
||||
return Cci.PrimitiveTypeCode.NotPrimitive;
|
||||
}
|
||||
|
||||
TypeDefinitionHandle Cci.ITypeReference.TypeDef
|
||||
{
|
||||
get
|
||||
{
|
||||
//PENamedTypeSymbol peNamedType = this as PENamedTypeSymbol;
|
||||
//if ((object)peNamedType != null)
|
||||
//{
|
||||
// return peNamedType.Handle;
|
||||
//}
|
||||
|
||||
throw new System.NotImplementedException();
|
||||
|
||||
//return default(TypeDefinitionHandle);
|
||||
}
|
||||
}
|
||||
|
||||
Cci.IGenericMethodParameterReference Cci.ITypeReference.AsGenericMethodParameterReference
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
Cci.IGenericTypeInstanceReference Cci.ITypeReference.AsGenericTypeInstanceReference
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(this.IsDefinitionOrDistinct());
|
||||
|
||||
if (!this.IsDefinition &&
|
||||
this.Arity > 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Cci.IGenericTypeParameterReference Cci.ITypeReference.AsGenericTypeParameterReference
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
Cci.INamespaceTypeReference Cci.ITypeReference.AsNamespaceTypeReference
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(this.IsDefinitionOrDistinct());
|
||||
|
||||
if (this.IsDefinition &&
|
||||
(object)this.ContainingType == null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Cci.INamespaceTypeDefinition Cci.ITypeReference.AsNamespaceTypeDefinition(EmitContext context)
|
||||
{
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
Debug.Assert(this.IsDefinitionOrDistinct());
|
||||
|
||||
if ((object)this.ContainingType == null &&
|
||||
this.IsDefinition &&
|
||||
this.ContainingModule == moduleBeingBuilt.SourceModule)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Cci.INestedTypeReference Cci.ITypeReference.AsNestedTypeReference
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((object)this.ContainingType != null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Cci.INestedTypeDefinition Cci.ITypeReference.AsNestedTypeDefinition(EmitContext context)
|
||||
{
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
return AsNestedTypeDefinitionImpl(moduleBeingBuilt);
|
||||
}
|
||||
|
||||
private Cci.INestedTypeDefinition AsNestedTypeDefinitionImpl(PEModuleBuilder moduleBeingBuilt)
|
||||
{
|
||||
Debug.Assert(this.IsDefinitionOrDistinct());
|
||||
|
||||
if ((object)this.ContainingType != null &&
|
||||
this.IsDefinition &&
|
||||
this.ContainingModule == moduleBeingBuilt.SourceModule)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Cci.ISpecializedNestedTypeReference Cci.ITypeReference.AsSpecializedNestedTypeReference
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(this.IsDefinitionOrDistinct());
|
||||
|
||||
throw new System.NotImplementedException();
|
||||
|
||||
//if (!this.IsDefinition &&
|
||||
// (this.Arity == 0 || PEModuleBuilder.IsGenericType(this.ContainingType)))
|
||||
//{
|
||||
// Debug.Assert((object)this.ContainingType != null &&
|
||||
// PEModuleBuilder.IsGenericType(this.ContainingType));
|
||||
// return this;
|
||||
//}
|
||||
|
||||
//return null;
|
||||
}
|
||||
}
|
||||
|
||||
Cci.ITypeDefinition Cci.ITypeReference.AsTypeDefinition(EmitContext context)
|
||||
{
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
return AsTypeDefinitionImpl(moduleBeingBuilt);
|
||||
}
|
||||
|
||||
private Cci.ITypeDefinition AsTypeDefinitionImpl(PEModuleBuilder moduleBeingBuilt)
|
||||
{
|
||||
Debug.Assert(this.IsDefinitionOrDistinct());
|
||||
|
||||
if (this.IsDefinition && // can't be generic instantiation
|
||||
this.ContainingModule == moduleBeingBuilt.SourceModule) // must be declared in the module we are building
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void Cci.IReference.Dispatch(Cci.MetadataVisitor visitor)
|
||||
{
|
||||
throw ExceptionUtilities.Unreachable;
|
||||
//We've not yet discovered a scenario in which we need this.
|
||||
//If you're hitting this exception. Uncomment the code below
|
||||
//and add a unit test.
|
||||
}
|
||||
|
||||
Cci.IDefinition Cci.IReference.AsDefinition(EmitContext context)
|
||||
{
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
return AsTypeDefinitionImpl(moduleBeingBuilt);
|
||||
}
|
||||
|
||||
Cci.ITypeReference Cci.ITypeDefinition.GetBaseClass(EmitContext context)
|
||||
{
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
//Debug.Assert(((Cci.ITypeReference)this).AsTypeDefinition(context) != null);
|
||||
//NamedTypeSymbol baseType = this.BaseTypeNoUseSiteDiagnostics;
|
||||
|
||||
//if (this.TypeKind == TypeKind.Submission)
|
||||
//{
|
||||
// // although submission semantically doesn't have a base we need to emit one into metadata:
|
||||
// Debug.Assert((object)baseType == null);
|
||||
// baseType = this.ContainingAssembly.GetSpecialType(Microsoft.CodeAnalysis.SpecialType.System_Object);
|
||||
//}
|
||||
|
||||
//return ((object)baseType != null) ? moduleBeingBuilt.Translate(baseType,
|
||||
// syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt,
|
||||
// diagnostics: context.Diagnostics) : null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
IEnumerable<Cci.IEventDefinition> Cci.ITypeDefinition.Events
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return GetEventsToEmit().Cast<Cci.IEventDefinition>();
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual IEnumerable<IEventSymbol> GetEventsToEmit()
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
foreach (var m in this.GetMembers())
|
||||
{
|
||||
if (m.Kind == SymbolKind.Event)
|
||||
{
|
||||
//yield return (EventSymbol)m;
|
||||
}
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
IEnumerable<Cci.MethodImplementation> Cci.ITypeDefinition.GetExplicitImplementationOverrides(EmitContext context)
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
if (this.TypeKind == TypeKind.Interface)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
foreach (var member in this.GetMembers())
|
||||
{
|
||||
if (member.Kind == SymbolKind.Method)
|
||||
{
|
||||
//var method = (MethodSymbol)member;
|
||||
//Debug.Assert((object)method.PartialDefinitionPart == null); // must be definition
|
||||
|
||||
//var explicitImplementations = method.ExplicitInterfaceImplementations;
|
||||
//if (explicitImplementations.Length != 0)
|
||||
//{
|
||||
// foreach (var implemented in method.ExplicitInterfaceImplementations)
|
||||
// {
|
||||
// yield return new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(implemented, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics));
|
||||
// }
|
||||
//}
|
||||
|
||||
//if (method.RequiresExplicitOverride())
|
||||
//{
|
||||
// // If C# and the runtime don't agree on the overridden method, then
|
||||
// // we will mark the method as newslot (see MethodSymbolAdapter) and
|
||||
// // specify the override explicitly.
|
||||
// // This mostly affects accessors - C# ignores method interactions
|
||||
// // between accessors and non-accessors, whereas the runtime does not.
|
||||
// yield return new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(method.OverriddenMethod, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics));
|
||||
//}
|
||||
//else if (method.MethodKind == MethodKind.Destructor && this.SpecialType != SpecialType.System_Object)
|
||||
//{
|
||||
// // New in Roslyn: all destructors explicitly override (or are) System.Object.Finalize so that
|
||||
// // they are guaranteed to be runtime finalizers. As a result, it is no longer possible to create
|
||||
// // a destructor that will never be invoked by the runtime.
|
||||
// // NOTE: If System.Object doesn't contain a destructor, you're on your own - this destructor may
|
||||
// // or not be called by the runtime.
|
||||
// TypeSymbol objectType = this.DeclaringCompilation.GetSpecialType(CodeAnalysis.SpecialType.System_Object);
|
||||
// foreach (Symbol objectMember in objectType.GetMembers(WellKnownMemberNames.DestructorName))
|
||||
// {
|
||||
// MethodSymbol objectMethod = objectMember as MethodSymbol;
|
||||
// if ((object)objectMethod != null && objectMethod.MethodKind == MethodKind.Destructor)
|
||||
// {
|
||||
// yield return new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(objectMethod, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics));
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
//var syntheticMethods = moduleBeingBuilt.GetSynthesizedMethods(this);
|
||||
//if (syntheticMethods != null)
|
||||
//{
|
||||
// foreach (var m in syntheticMethods)
|
||||
// {
|
||||
// var method = m as MethodSymbol;
|
||||
// if ((object)method != null)
|
||||
// {
|
||||
// foreach (var implemented in method.ExplicitInterfaceImplementations)
|
||||
// {
|
||||
// Debug.Assert((object)method.PartialDefinitionPart == null); // must be definition
|
||||
// yield return new Microsoft.Cci.MethodImplementation(method, moduleBeingBuilt.TranslateOverriddenMethodReference(implemented, (CSharpSyntaxNode)context.SyntaxNodeOpt, context.Diagnostics));
|
||||
// }
|
||||
|
||||
// Debug.Assert(!method.RequiresExplicitOverride());
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
IEnumerable<Cci.IFieldDefinition> Cci.ITypeDefinition.GetFields(EmitContext context)
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
foreach (var f in GetFieldsToEmit())
|
||||
{
|
||||
yield return (Cci.IFieldDefinition)f;
|
||||
}
|
||||
|
||||
//IEnumerable<Cci.IFieldDefinition> generated = ((PEModuleBuilder)context.Module).GetSynthesizedFields(this);
|
||||
|
||||
//if (generated != null)
|
||||
//{
|
||||
// foreach (var f in generated)
|
||||
// {
|
||||
// yield return f;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
internal abstract IEnumerable<IFieldSymbol> GetFieldsToEmit();
|
||||
|
||||
IEnumerable<Cci.IGenericTypeParameter> Cci.ITypeDefinition.GenericParameters
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
foreach (var t in this.TypeParameters)
|
||||
{
|
||||
yield return (Cci.IGenericTypeParameter)t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ushort Cci.ITypeDefinition.GenericParameterCount
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
return GenericParameterCountImpl;
|
||||
}
|
||||
}
|
||||
|
||||
private ushort GenericParameterCountImpl
|
||||
{
|
||||
get { return (ushort)this.Arity; }
|
||||
}
|
||||
|
||||
IEnumerable<Cci.ITypeReference> Cci.ITypeDefinition.Interfaces(EmitContext context)
|
||||
{
|
||||
Debug.Assert(((Cci.ITypeReference)this).AsTypeDefinition(context) != null);
|
||||
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
foreach (NamedTypeSymbol @interface in this.GetInterfacesToEmit())
|
||||
{
|
||||
//yield return moduleBeingBuilt.Translate(@interface,
|
||||
// syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt,
|
||||
// diagnostics: context.Diagnostics,
|
||||
// fromImplements: true);
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the set of interfaces to emit on this type. This set can be different from the set returned by Interfaces property.
|
||||
/// </summary>
|
||||
internal abstract ImmutableArray<NamedTypeSymbol> GetInterfacesToEmit();
|
||||
|
||||
bool Cci.ITypeDefinition.IsAbstract
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return IsMetadataAbstract;
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual bool IsMetadataAbstract
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return this.IsAbstract || this.IsStatic;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsBeforeFieldInit
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
switch (this.TypeKind)
|
||||
{
|
||||
case TypeKind.Enum:
|
||||
case TypeKind.Delegate:
|
||||
//C# interfaces don't have fields so the flag doesn't really matter, but Dev10 omits it
|
||||
case TypeKind.Interface:
|
||||
return false;
|
||||
}
|
||||
|
||||
//apply the beforefieldinit attribute unless there is an explicitly specified static constructor
|
||||
foreach (var member in GetMembers(WellKnownMemberNames.StaticConstructorName))
|
||||
{
|
||||
if (!member.IsImplicitlyDeclared)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsComObject
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsGeneric
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return this.Arity != 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsInterface
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return this.TypeKind == TypeKind.Interface;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsRuntimeSpecial
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsSerializable
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return false; // this.IsSerializable;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsSpecialName
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return false; // this.HasSpecialName;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsWindowsRuntimeImport
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return true; // this.IsWindowsRuntimeImport;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.IsSealed
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return this.IsMetadataSealed;
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual bool IsMetadataSealed
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return this.IsSealed || this.IsStatic;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<Cci.IMethodDefinition> Cci.ITypeDefinition.GetMethods(EmitContext context)
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
foreach (var method in this.GetMethodsToEmit())
|
||||
{
|
||||
Debug.Assert((object)method != null);
|
||||
yield return (Cci.IMethodDefinition)method;
|
||||
}
|
||||
|
||||
//IEnumerable<Cci.IMethodDefinition> generated = ((PEModuleBuilder)context.Module).GetSynthesizedMethods(this);
|
||||
|
||||
//if (generated != null)
|
||||
//{
|
||||
// foreach (var m in generated)
|
||||
// {
|
||||
// yield return m;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To represent a gap in interface's v-table null value should be returned in the appropriate position,
|
||||
/// unless the gap has a symbol (happens if it is declared in source, for example).
|
||||
/// </summary>
|
||||
internal virtual IEnumerable<IMethodSymbol> GetMethodsToEmit()
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
foreach (var m in this.GetMembers())
|
||||
{
|
||||
if (m.Kind == SymbolKind.Method)
|
||||
{
|
||||
var method = (IMethodSymbol)m;
|
||||
|
||||
//if (method.IsPartialDefinition())
|
||||
//{
|
||||
// // Don't emit partial methods without an implementation part.
|
||||
// if ((object)method.PartialImplementationPart == null)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
//}
|
||||
//// Don't emit the default value type constructor - the runtime handles that
|
||||
//else if (method.IsDefaultValueTypeConstructor())
|
||||
//{
|
||||
// continue;
|
||||
//}
|
||||
|
||||
yield return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<Cci.INestedTypeDefinition> Cci.ITypeDefinition.GetNestedTypes(EmitContext context)
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
foreach (NamedTypeSymbol type in this.GetTypeMembers()) // Ordered.
|
||||
{
|
||||
yield return type;
|
||||
}
|
||||
|
||||
//IEnumerable<Cci.INestedTypeDefinition> generated = ((PEModuleBuilder)context.Module).GetSynthesizedTypes(this);
|
||||
|
||||
//if (generated != null)
|
||||
//{
|
||||
// foreach (var t in generated)
|
||||
// {
|
||||
// yield return t;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
IEnumerable<Cci.IPropertyDefinition> Cci.ITypeDefinition.GetProperties(EmitContext context)
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
foreach (var property in this.GetPropertiesToEmit())
|
||||
{
|
||||
Debug.Assert((object)property != null);
|
||||
yield return (Cci.IPropertyDefinition)property;
|
||||
}
|
||||
|
||||
//IEnumerable<Cci.IPropertyDefinition> generated = ((PEModuleBuilder)context.Module).GetSynthesizedProperties(this);
|
||||
|
||||
//if (generated != null)
|
||||
//{
|
||||
// foreach (var m in generated)
|
||||
// {
|
||||
// yield return m;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
internal virtual IEnumerable<IPropertySymbol> GetPropertiesToEmit()
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
foreach (var m in this.GetMembers())
|
||||
{
|
||||
if (m.Kind == SymbolKind.Property)
|
||||
{
|
||||
yield return (IPropertySymbol)m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.ITypeDefinition.HasDeclarativeSecurity
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return false; // this.HasDeclarativeSecurity;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<Cci.SecurityAttribute> Cci.ITypeDefinition.SecurityAttributes
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return /*this.GetSecurityInformation() ??*/ SpecializedCollections.EmptyEnumerable<Cci.SecurityAttribute>();
|
||||
}
|
||||
}
|
||||
|
||||
ushort Cci.ITypeDefinition.Alignment
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
var layout = this.Layout;
|
||||
return (ushort)layout.Alignment;
|
||||
}
|
||||
}
|
||||
|
||||
LayoutKind Cci.ITypeDefinition.Layout
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return this.Layout.Kind;
|
||||
}
|
||||
}
|
||||
|
||||
uint Cci.ITypeDefinition.SizeOf
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
return (uint)this.Layout.Size;
|
||||
}
|
||||
}
|
||||
|
||||
CharSet Cci.ITypeDefinition.StringFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
return CharSet.Ansi; // this.MarshallingCharSet; //throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
ushort Cci.INamedTypeReference.GenericParameterCount
|
||||
{
|
||||
get { return GenericParameterCountImpl; }
|
||||
}
|
||||
|
||||
bool Cci.INamedTypeReference.MangleName
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.Arity != 0;
|
||||
}
|
||||
}
|
||||
|
||||
string Cci.INamedEntity.Name
|
||||
{
|
||||
get
|
||||
{
|
||||
string unsuffixedName = this.Name;
|
||||
|
||||
// CLR generally allows names with dots, however some APIs like IMetaDataImport
|
||||
// can only return full type names combined with namespaces.
|
||||
// see: http://msdn.microsoft.com/en-us/library/ms230143.aspx (IMetaDataImport::GetTypeDefProps)
|
||||
// When working with such APIs, names with dots become ambiguous since metadata
|
||||
// consumer cannot figure where namespace ends and actual type name starts.
|
||||
// Therefore it is a good practice to avoid type names with dots.
|
||||
// Exception: The EE copies type names from metadata, which may contain dots already.
|
||||
//Debug.Assert(this.IsErrorType() ||
|
||||
// !unsuffixedName.Contains(".") ||
|
||||
// this.OriginalDefinition is PENamedTypeSymbol, "type name contains dots: " + unsuffixedName);
|
||||
|
||||
return unsuffixedName;
|
||||
}
|
||||
}
|
||||
|
||||
Cci.IUnitReference Cci.INamespaceTypeReference.GetUnit(EmitContext context)
|
||||
{
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
Debug.Assert(((Cci.ITypeReference)this).AsNamespaceTypeReference != null);
|
||||
Debug.Assert(this.ContainingAssembly != null);
|
||||
return moduleBeingBuilt.Translate(this.ContainingAssembly, context.Diagnostics);
|
||||
}
|
||||
|
||||
string Cci.INamespaceTypeReference.NamespaceName
|
||||
{
|
||||
get
|
||||
{
|
||||
// INamespaceTypeReference is a type contained in a namespace
|
||||
// if this method is called for a nested type, we are in big trouble.
|
||||
Debug.Assert(((Cci.ITypeReference)this).AsNamespaceTypeReference != null);
|
||||
var ns = this.ContainingSymbol as INamespaceSymbol;
|
||||
if (ns != null)
|
||||
{
|
||||
return ns.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cci.INamespaceTypeDefinition.IsPublic
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert((object)this.ContainingType == null && this.ContainingModule is SourceModuleSymbol);
|
||||
|
||||
return PEModuleBuilder.MemberVisibility(this) == Cci.TypeMemberVisibility.Public;
|
||||
}
|
||||
}
|
||||
|
||||
Cci.ITypeReference Cci.ITypeMemberReference.GetContainingType(EmitContext context)
|
||||
{
|
||||
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
|
||||
Debug.Assert(((Cci.ITypeReference)this).AsNestedTypeReference != null);
|
||||
|
||||
Debug.Assert(this.IsDefinitionOrDistinct());
|
||||
|
||||
if (!this.IsDefinition)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
//return moduleBeingBuilt.Translate(this.ContainingType,
|
||||
// syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt,
|
||||
// diagnostics: context.Diagnostics);
|
||||
}
|
||||
|
||||
return (Cci.ITypeReference)this.ContainingType;
|
||||
}
|
||||
|
||||
Cci.ITypeDefinition Cci.ITypeDefinitionMember.ContainingTypeDefinition
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert((object)this.ContainingType != null);
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
return (Cci.ITypeDefinition)this.ContainingType;
|
||||
}
|
||||
}
|
||||
|
||||
Cci.TypeMemberVisibility Cci.ITypeDefinitionMember.Visibility
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert((object)this.ContainingType != null);
|
||||
CheckDefinitionInvariant();
|
||||
|
||||
return PEModuleBuilder.MemberVisibility(this);
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableArray<Cci.ITypeReference> Cci.IGenericTypeInstanceReference.GetGenericArguments(EmitContext context)
|
||||
{
|
||||
//PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
|
||||
//var builder = ArrayBuilder<Microsoft.Cci.ITypeReference>.GetInstance();
|
||||
//Debug.Assert(((Cci.ITypeReference)this).AsGenericTypeInstanceReference != null);
|
||||
|
||||
//var modifiers = default(ImmutableArray<ImmutableArray<CustomModifier>>);
|
||||
|
||||
//if (this.HasTypeArgumentsCustomModifiers)
|
||||
//{
|
||||
// modifiers = this.TypeArgumentsCustomModifiers;
|
||||
//}
|
||||
|
||||
//var arguments = this.TypeArgumentsNoUseSiteDiagnostics;
|
||||
|
||||
//for (int i = 0; i < arguments.Length; i++)
|
||||
//{
|
||||
// var arg = moduleBeingBuilt.Translate(arguments[i], syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt, diagnostics: context.Diagnostics);
|
||||
|
||||
// if (!modifiers.IsDefault && !modifiers[i].IsDefaultOrEmpty)
|
||||
// {
|
||||
// arg = new Cci.ModifiedTypeReference(arg, modifiers[i].As<Cci.ICustomModifier>());
|
||||
// }
|
||||
|
||||
// builder.Add(arg);
|
||||
//}
|
||||
|
||||
//return builder.ToImmutableAndFree();
|
||||
|
||||
return ImmutableArray<Cci.ITypeReference>.Empty;
|
||||
}
|
||||
|
||||
Cci.INamedTypeReference Cci.IGenericTypeInstanceReference.GenericType
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(((Cci.ITypeReference)this).AsGenericTypeInstanceReference != null);
|
||||
return GenericTypeImpl;
|
||||
}
|
||||
}
|
||||
|
||||
private Cci.INamedTypeReference GenericTypeImpl
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Cci.INamedTypeReference)this.OriginalDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
Cci.INestedTypeReference Cci.ISpecializedNestedTypeReference.UnspecializedVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(((Cci.ITypeReference)this).AsSpecializedNestedTypeReference != null);
|
||||
var result = GenericTypeImpl.AsNestedTypeReference;
|
||||
|
||||
Debug.Assert(result != null);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using Cci = Microsoft.Cci;
|
||||
|
||||
namespace Pchp.CodeAnalysis.Symbols
|
||||
{
|
||||
internal partial class NamespaceSymbol : Cci.INamespace
|
||||
{
|
||||
Cci.INamespace Cci.INamespace.ContainingNamespace => this.ContainingNamespace as Cci.INamespace;
|
||||
string Cci.INamedEntity.Name => MetadataName;
|
||||
}
|
||||
}
|
|
@ -43,7 +43,7 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
IEnumerable<ResourceDescription> manifestResources,
|
||||
OutputKind outputKind,
|
||||
EmitOptions emitOptions)
|
||||
:base(sourceAssembly.DeclaringCompilation, sourceAssembly.Modules[0], serializationProperties, manifestResources, outputKind, emitOptions)
|
||||
:base(sourceAssembly.DeclaringCompilation, (SourceModuleSymbol)sourceAssembly.Modules[0], serializationProperties, manifestResources, outputKind, emitOptions)
|
||||
{
|
||||
_sourceAssembly = sourceAssembly;
|
||||
_metadataName = (emitOptions.OutputNameOverride == null) ? sourceAssembly.MetadataName : FileNameUtilities.ChangeExtension(emitOptions.OutputNameOverride, extension: null);
|
||||
|
|
|
@ -14,12 +14,13 @@ using Roslyn.Utilities;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Cci = Microsoft.Cci;
|
||||
using Microsoft.CodeAnalysis.Emit.NoPia;
|
||||
using Pchp.CodeAnalysis.Symbols;
|
||||
|
||||
namespace Pchp.CodeAnalysis.Emit
|
||||
{
|
||||
internal class PEModuleBuilder : CommonPEModuleBuilder, Cci.IModule, ITokenDeferral
|
||||
{
|
||||
private readonly IModuleSymbol _sourceModule;
|
||||
private readonly SourceModuleSymbol _sourceModule;
|
||||
private readonly PhpCompilation _compilation;
|
||||
private readonly OutputKind _outputKind;
|
||||
private readonly EmitOptions _emitOptions;
|
||||
|
@ -27,7 +28,10 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
|
||||
readonly StringTokenMap _stringsInILMap = new StringTokenMap();
|
||||
readonly TokenMap<Cci.IReference> _referencesInILMap = new TokenMap<Cci.IReference>();
|
||||
readonly Cci.RootModuleType _rootModuleType = new Cci.RootModuleType();
|
||||
Cci.IMethodReference _peEntryPoint, _debugEntryPoint;
|
||||
PrivateImplementationDetails _privateImplementationDetails;
|
||||
HashSet<string> _namesOfTopLevelTypes; // initialized with set of type names within first call to GetTopLevelTypes()
|
||||
|
||||
internal readonly IEnumerable<ResourceDescription> ManifestResources;
|
||||
internal readonly CommonModuleCompilationState CompilationState;
|
||||
|
@ -42,7 +46,7 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
|
||||
protected PEModuleBuilder(
|
||||
PhpCompilation compilation,
|
||||
IModuleSymbol sourceModule,
|
||||
SourceModuleSymbol sourceModule,
|
||||
Cci.ModulePropertiesForSerialization serializationProperties,
|
||||
IEnumerable<ResourceDescription> manifestResources,
|
||||
OutputKind outputKind,
|
||||
|
@ -61,6 +65,8 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
_debugDocuments = new ConcurrentDictionary<string, Cci.DebugSourceDocument>(compilation.IsCaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public IModuleSymbol SourceModule => _sourceModule;
|
||||
|
||||
public ArrayMethods ArrayMethods
|
||||
{
|
||||
get
|
||||
|
@ -135,7 +141,9 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
{
|
||||
get
|
||||
{
|
||||
yield break; // throw new NotImplementedException();
|
||||
// Let's not add any module references explicitly,
|
||||
// PeWriter will implicitly add those needed.
|
||||
return SpecializedCollections.EmptyEnumerable<Cci.IModuleReference>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,14 +213,6 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
|
||||
internal override EmitOptions EmitOptions => _emitOptions;
|
||||
|
||||
internal override bool SupportsPrivateImplClass
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public Cci.IDefinition AsDefinition(EmitContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
@ -356,7 +356,233 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
|
||||
public IEnumerable<Cci.INamespaceTypeDefinition> GetTopLevelTypes(EmitContext context)
|
||||
{
|
||||
return ImmutableArray<Cci.INamespaceTypeDefinition>.Empty; //throw new NotImplementedException();
|
||||
Cci.NoPiaReferenceIndexer noPiaIndexer = null;
|
||||
|
||||
// First time through, we need to collect emitted names of all top level types.
|
||||
HashSet<string> names = (_namesOfTopLevelTypes == null) ? new HashSet<string>() : null;
|
||||
|
||||
//// First time through, we need to push things through NoPiaReferenceIndexer
|
||||
//// to make sure we collect all to be embedded NoPia types and members.
|
||||
//if (EmbeddedTypesManagerOpt != null && !EmbeddedTypesManagerOpt.IsFrozen)
|
||||
//{
|
||||
// noPiaIndexer = new Cci.NoPiaReferenceIndexer(context);
|
||||
// Debug.Assert(names != null);
|
||||
// this.Dispatch(noPiaIndexer);
|
||||
//}
|
||||
|
||||
AddTopLevelType(names, _rootModuleType);
|
||||
VisitTopLevelType(noPiaIndexer, _rootModuleType);
|
||||
yield return _rootModuleType;
|
||||
|
||||
foreach (var type in this.GetAnonymousTypes())
|
||||
{
|
||||
AddTopLevelType(names, type);
|
||||
VisitTopLevelType(noPiaIndexer, type);
|
||||
yield return type;
|
||||
}
|
||||
|
||||
foreach (var type in this.GetTopLevelTypesCore(context))
|
||||
{
|
||||
AddTopLevelType(names, type);
|
||||
VisitTopLevelType(noPiaIndexer, type);
|
||||
yield return type;
|
||||
}
|
||||
|
||||
var privateImpl = this.PrivateImplClass;
|
||||
if (privateImpl != null)
|
||||
{
|
||||
AddTopLevelType(names, privateImpl);
|
||||
VisitTopLevelType(noPiaIndexer, privateImpl);
|
||||
yield return privateImpl;
|
||||
}
|
||||
|
||||
//if (EmbeddedTypesManagerOpt != null)
|
||||
//{
|
||||
// foreach (var embedded in EmbeddedTypesManagerOpt.GetTypes(context.Diagnostics, names))
|
||||
// {
|
||||
// AddTopLevelType(names, embedded);
|
||||
// yield return embedded;
|
||||
// }
|
||||
//}
|
||||
|
||||
if (names != null)
|
||||
{
|
||||
Debug.Assert(_namesOfTopLevelTypes == null);
|
||||
_namesOfTopLevelTypes = names;
|
||||
}
|
||||
}
|
||||
|
||||
// DEBUG: to declarations map
|
||||
List<SourceNamedTypeSymbol> _types = null;
|
||||
|
||||
|
||||
internal virtual IEnumerable<Cci.INamespaceTypeDefinition> GetTopLevelTypesCore(EmitContext context)
|
||||
{
|
||||
//foreach (var type in GetAdditionalTopLevelTypes())
|
||||
//{
|
||||
// yield return type;
|
||||
//}
|
||||
|
||||
if (_types == null)
|
||||
{
|
||||
// DEBUG: to declarations map
|
||||
_types = new List<SourceNamedTypeSymbol>();
|
||||
foreach (var t in _compilation._syntaxtreestmp.SelectMany(u => u.Ast.Statements).OfType<Syntax.AST.TypeDecl>())
|
||||
{
|
||||
_types.Add(new SourceNamedTypeSymbol(_sourceModule, t));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var t in _types)
|
||||
yield return t;
|
||||
|
||||
//var namespacesToProcess = new Stack<INamespaceSymbol>();
|
||||
//namespacesToProcess.Push(this.SourceModule.GlobalNamespace);
|
||||
|
||||
//while (namespacesToProcess.Count != 0)
|
||||
//{
|
||||
// var ns = namespacesToProcess.Pop();
|
||||
// foreach (var member in ns.GetMembers())
|
||||
// {
|
||||
// var memberNamespace = member as INamespaceSymbol;
|
||||
// if (memberNamespace != null)
|
||||
// {
|
||||
// namespacesToProcess.Push(memberNamespace);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var type = (NamedTypeSymbol)member;
|
||||
// yield return type;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
public static Cci.TypeMemberVisibility MemberVisibility(Symbol symbol)
|
||||
{
|
||||
//
|
||||
// We need to relax visibility of members in interactive submissions since they might be emitted into multiple assemblies.
|
||||
//
|
||||
// Top-level:
|
||||
// private -> public
|
||||
// protected -> public (compiles with a warning)
|
||||
// public
|
||||
// internal -> public
|
||||
//
|
||||
// In a nested class:
|
||||
//
|
||||
// private
|
||||
// protected
|
||||
// public
|
||||
// internal -> public
|
||||
//
|
||||
switch (symbol.DeclaredAccessibility)
|
||||
{
|
||||
case Accessibility.Public:
|
||||
return Cci.TypeMemberVisibility.Public;
|
||||
|
||||
case Accessibility.Private:
|
||||
if (symbol.ContainingType.TypeKind == TypeKind.Submission)
|
||||
{
|
||||
// top-level private member:
|
||||
return Cci.TypeMemberVisibility.Public;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Cci.TypeMemberVisibility.Private;
|
||||
}
|
||||
|
||||
case Accessibility.Internal:
|
||||
if (symbol.ContainingAssembly.IsInteractive)
|
||||
{
|
||||
// top-level or nested internal member:
|
||||
return Cci.TypeMemberVisibility.Public;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Cci.TypeMemberVisibility.Assembly;
|
||||
}
|
||||
|
||||
case Accessibility.Protected:
|
||||
if (symbol.ContainingType.TypeKind == TypeKind.Submission)
|
||||
{
|
||||
// top-level protected member:
|
||||
return Cci.TypeMemberVisibility.Public;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Cci.TypeMemberVisibility.Family;
|
||||
}
|
||||
|
||||
case Accessibility.ProtectedAndInternal: // Not supported by language, but we should be able to import it.
|
||||
Debug.Assert(symbol.ContainingType.TypeKind != TypeKind.Submission);
|
||||
return Cci.TypeMemberVisibility.FamilyAndAssembly;
|
||||
|
||||
case Accessibility.ProtectedOrInternal:
|
||||
if (symbol.ContainingAssembly.IsInteractive)
|
||||
{
|
||||
// top-level or nested protected internal member:
|
||||
return Cci.TypeMemberVisibility.Public;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Cci.TypeMemberVisibility.FamilyOrAssembly;
|
||||
}
|
||||
|
||||
default:
|
||||
throw ExceptionUtilities.UnexpectedValue(symbol.DeclaredAccessibility);
|
||||
}
|
||||
}
|
||||
|
||||
#region Private Implementation Details Type
|
||||
|
||||
internal PrivateImplementationDetails GetPrivateImplClass(SyntaxNode syntaxNodeOpt, DiagnosticBag diagnostics)
|
||||
{
|
||||
var result = _privateImplementationDetails;
|
||||
|
||||
if ((result == null) && this.SupportsPrivateImplClass)
|
||||
{
|
||||
//result = new PrivateImplementationDetails(
|
||||
// this,
|
||||
// _sourceModule.Name,
|
||||
// _compilation.GetSubmissionSlotIndex(),
|
||||
// this.GetSpecialType(SpecialType.System_Object, syntaxNodeOpt, diagnostics),
|
||||
// this.GetSpecialType(SpecialType.System_ValueType, syntaxNodeOpt, diagnostics),
|
||||
// this.GetSpecialType(SpecialType.System_Byte, syntaxNodeOpt, diagnostics),
|
||||
// this.GetSpecialType(SpecialType.System_Int16, syntaxNodeOpt, diagnostics),
|
||||
// this.GetSpecialType(SpecialType.System_Int32, syntaxNodeOpt, diagnostics),
|
||||
// this.GetSpecialType(SpecialType.System_Int64, syntaxNodeOpt, diagnostics),
|
||||
// SynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor));
|
||||
|
||||
if (Interlocked.CompareExchange(ref _privateImplementationDetails, result, null) != null)
|
||||
{
|
||||
result = _privateImplementationDetails;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal PrivateImplementationDetails PrivateImplClass
|
||||
{
|
||||
get { return _privateImplementationDetails; }
|
||||
}
|
||||
|
||||
internal override bool SupportsPrivateImplClass
|
||||
{
|
||||
get { return false; } // TODO: true when GetSpecialType() will be implemented
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
static void AddTopLevelType(HashSet<string> names, Cci.INamespaceTypeDefinition type)
|
||||
{
|
||||
names?.Add(MetadataHelpers.BuildQualifiedName(type.NamespaceName, Cci.MetadataWriter.GetMangledName(type)));
|
||||
}
|
||||
|
||||
static void VisitTopLevelType(Cci.NoPiaReferenceIndexer noPiaIndexer, Cci.INamespaceTypeDefinition type)
|
||||
{
|
||||
noPiaIndexer?.Visit((Cci.ITypeDefinition)type);
|
||||
}
|
||||
|
||||
public bool IsPlatformType(Cci.ITypeReference typeRef, Cci.PlatformType t)
|
||||
|
@ -381,7 +607,7 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
|
||||
internal override ImmutableArray<Cci.INamespaceTypeDefinition> GetAnonymousTypes()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return ImmutableArray<Cci.INamespaceTypeDefinition>.Empty; // throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal override ImmutableDictionary<Cci.ITypeDefinition, ImmutableArray<Cci.ITypeDefinitionMember>> GetSynthesizedMembers()
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Pchp.CodeAnalysis.Emit
|
|||
EmitOptions emitOptions,
|
||||
Microsoft.Cci.ModulePropertiesForSerialization serializationProperties,
|
||||
IEnumerable<ResourceDescription> manifestResources)
|
||||
: base(compilation, sourceModule, serializationProperties, manifestResources, OutputKind.NetModule, emitOptions)
|
||||
: base(compilation, (Symbols.SourceModuleSymbol)sourceModule, serializationProperties, manifestResources, OutputKind.NetModule, emitOptions)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,16 @@ namespace Pchp.CodeAnalysis
|
|||
// (this.Kind == SymbolKind.NetModule && this is SourceModuleSymbol));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return whether the symbol is either the original definition
|
||||
/// or distinct from the original. Intended for use in Debug.Assert
|
||||
/// only since it may include a deep comparison.
|
||||
/// </summary>
|
||||
internal bool IsDefinitionOrDistinct()
|
||||
{
|
||||
return this.IsDefinition || !this.Equals(this.OriginalDefinition);
|
||||
}
|
||||
|
||||
Cci.IDefinition Cci.IReference.AsDefinition(EmitContext context)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
<Compile Include="Compilation\PhpCompilationOptions.cs" />
|
||||
<Compile Include="Compilation\ReferenceManager.cs" />
|
||||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="Emitter\Model\NamedTypeSymbolAdapter.cs" />
|
||||
<Compile Include="Emitter\Model\NamespaceSymbolAdapter.cs" />
|
||||
<Compile Include="Emitter\Model\PEAssemblyBuilder.cs" />
|
||||
<Compile Include="Emitter\Model\PEModuleBuilder.cs" />
|
||||
<Compile Include="Emitter\Model\PENetModuleBuilder.cs" />
|
||||
|
@ -69,9 +71,14 @@
|
|||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Symbols\AssemblySymbol.cs" />
|
||||
<Compile Include="Symbols\NamedTypeSymbol.cs" />
|
||||
<Compile Include="Symbols\NamespaceOrTypeSymbol.cs" />
|
||||
<Compile Include="Symbols\NamespaceSymbol.cs" />
|
||||
<Compile Include="Symbols\Source\SourceAssemblySymbol.cs" />
|
||||
<Compile Include="Symbols\Source\SourceModuleSymbol.cs" />
|
||||
<Compile Include="Symbols\Source\SourceNamedTypeSymbol.cs" />
|
||||
<Compile Include="Symbols\Symbol.cs" />
|
||||
<Compile Include="Symbols\TypeSymbol.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="project.json" />
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Roslyn.Utilities;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Cci = Microsoft.Cci;
|
||||
|
||||
namespace Pchp.CodeAnalysis.Symbols
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a type other than an array, a pointer, a type parameter, and dynamic.
|
||||
/// </summary>
|
||||
internal abstract partial class NamedTypeSymbol : TypeSymbol, INamedTypeSymbol
|
||||
{
|
||||
public virtual int Arity
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0; //throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public ISymbol AssociatedSymbol => null;
|
||||
|
||||
public virtual INamedTypeSymbol ConstructedFrom
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ImmutableArray<IMethodSymbol> Constructors
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For delegate types, gets the delegate's invoke method. Returns null on
|
||||
/// all other kinds of types.
|
||||
/// </summary>
|
||||
public virtual IMethodSymbol DelegateInvokeMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO: look for __invoke method
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual INamedTypeSymbol EnumUnderlyingType => null;
|
||||
|
||||
public virtual ImmutableArray<IMethodSymbol> InstanceConstructors
|
||||
{
|
||||
get
|
||||
{
|
||||
// TODO: get constructors
|
||||
return ImmutableArray<IMethodSymbol>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsGenericType => false;
|
||||
|
||||
public virtual bool IsImplicitClass => false;
|
||||
|
||||
public virtual bool IsScriptClass => false;
|
||||
|
||||
public virtual bool IsUnboundGenericType => false;
|
||||
|
||||
public virtual IEnumerable<string> MemberNames
|
||||
{
|
||||
get
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type layout information (ClassLayout metadata and layout kind flags).
|
||||
/// </summary>
|
||||
internal abstract TypeLayout Layout { get; }
|
||||
|
||||
public virtual bool MightContainExtensionMethods
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ImmutableArray<IMethodSymbol> StaticConstructors
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray<IMethodSymbol>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ImmutableArray<ITypeSymbol> TypeArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray<ITypeSymbol>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ImmutableArray<ITypeParameterSymbol> TypeParameters
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray<ITypeParameterSymbol>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
INamedTypeSymbol INamedTypeSymbol.OriginalDefinition
|
||||
{
|
||||
get
|
||||
{
|
||||
return (INamedTypeSymbol)this.OriginalDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
#region ISymbol Members
|
||||
|
||||
public override void Accept(SymbolVisitor visitor)
|
||||
{
|
||||
visitor.VisitNamedType(this);
|
||||
}
|
||||
|
||||
public override TResult Accept<TResult>(SymbolVisitor<TResult> visitor)
|
||||
{
|
||||
return visitor.VisitNamedType(this);
|
||||
}
|
||||
|
||||
public INamedTypeSymbol Construct(params ITypeSymbol[] typeArguments)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public INamedTypeSymbol ConstructUnboundGenericType()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using Roslyn.Utilities;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
|
||||
namespace Pchp.CodeAnalysis.Symbols
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents either a namespace or a type.
|
||||
/// </summary>
|
||||
internal abstract class NamespaceOrTypeSymbol : Symbol, INamespaceOrTypeSymbol
|
||||
{
|
||||
// Only the compiler can create new instances.
|
||||
internal NamespaceOrTypeSymbol()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this symbol is a namespace. If it is not a namespace, it must be a type.
|
||||
/// </summary>
|
||||
public bool IsNamespace => Kind == SymbolKind.Namespace;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this symbols is a type. Equivalent to !IsNamespace.
|
||||
/// </summary>
|
||||
public bool IsType => !IsNamespace;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this symbol is "virtual", has an implementation, and does not override a
|
||||
/// base class member; i.e., declared with the "virtual" modifier. Does not return true for
|
||||
/// members declared as abstract or override.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Always returns false.
|
||||
/// </returns>
|
||||
public sealed override bool IsVirtual => false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this symbol was declared to override a base class member; i.e., declared
|
||||
/// with the "override" modifier. Still returns true if member was declared to override
|
||||
/// something, but (erroneously) no member to override exists.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Always returns false.
|
||||
/// </returns>
|
||||
public sealed override bool IsOverride => false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this symbol has external implementation; i.e., declared with the
|
||||
/// "extern" modifier.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// Always returns false.
|
||||
/// </returns>
|
||||
public sealed override bool IsExtern => false;
|
||||
|
||||
/// <summary>
|
||||
/// Get all the members of this symbol.
|
||||
/// </summary>
|
||||
/// <returns>An ImmutableArray containing all the members of this symbol. If this symbol has no members,
|
||||
/// returns an empty ImmutableArray. Never returns null.</returns>
|
||||
public abstract ImmutableArray<Symbol> GetMembers();
|
||||
|
||||
/// <summary>
|
||||
/// Get all the members of this symbol that have a particular name.
|
||||
/// </summary>
|
||||
/// <returns>An ImmutableArray containing all the members of this symbol with the given name. If there are
|
||||
/// no members with this name, returns an empty ImmutableArray. Never returns null.</returns>
|
||||
public abstract ImmutableArray<Symbol> GetMembers(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Get all the members of this symbol that are types.
|
||||
/// </summary>
|
||||
/// <returns>An ImmutableArray containing all the types that are members of this symbol. If this symbol has no type members,
|
||||
/// returns an empty ImmutableArray. Never returns null.</returns>
|
||||
public abstract ImmutableArray<NamedTypeSymbol> GetTypeMembers();
|
||||
|
||||
/// <summary>
|
||||
/// Get all the members of this symbol that are types that have a particular name, of any arity.
|
||||
/// </summary>
|
||||
/// <returns>An ImmutableArray containing all the types that are members of this symbol with the given name.
|
||||
/// If this symbol has no type members with this name,
|
||||
/// returns an empty ImmutableArray. Never returns null.</returns>
|
||||
public abstract ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Get all the members of this symbol that are types that have a particular name and arity
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerable containing all the types that are members of this symbol with the given name and arity.
|
||||
/// If this symbol has no type members with this name and arity,
|
||||
/// returns an empty IEnumerable. Never returns null.</returns>
|
||||
public virtual ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name, int arity)
|
||||
{
|
||||
// default implementation does a post-filter. We can override this if its a performance burden, but
|
||||
// experience is that it won't be.
|
||||
return GetTypeMembers(name).WhereAsArray(t => t.Arity == arity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds types or namespaces described by a qualified name.
|
||||
/// </summary>
|
||||
/// <param name="qualifiedName">Sequence of simple plain names.</param>
|
||||
/// <returns>
|
||||
/// A set of namespace or type symbols with given qualified name (might comprise of types with multiple generic arities),
|
||||
/// or an empty set if the member can't be found (the qualified name is ambiguous or the symbol doesn't exist).
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// "C.D" matches C.D, C{T}.D, C{S,T}.D{U}, etc.
|
||||
/// </remarks>
|
||||
internal IEnumerable<NamespaceOrTypeSymbol> GetNamespaceOrTypeByQualifiedName(IEnumerable<string> qualifiedName)
|
||||
{
|
||||
NamespaceOrTypeSymbol namespaceOrType = this;
|
||||
IEnumerable<NamespaceOrTypeSymbol> symbols = null;
|
||||
foreach (string name in qualifiedName)
|
||||
{
|
||||
if (symbols != null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
//// there might be multiple types of different arity, prefer a non-generic type:
|
||||
//namespaceOrType = symbols.OfMinimalArity();
|
||||
//if ((object)namespaceOrType == null)
|
||||
//{
|
||||
// return SpecializedCollections.EmptyEnumerable<NamespaceOrTypeSymbol>();
|
||||
//}
|
||||
}
|
||||
|
||||
symbols = namespaceOrType.GetMembers(name).OfType<NamespaceOrTypeSymbol>();
|
||||
}
|
||||
|
||||
return symbols;
|
||||
}
|
||||
|
||||
#region INamespaceOrTypeSymbol Members
|
||||
|
||||
ImmutableArray<ISymbol> INamespaceOrTypeSymbol.GetMembers()
|
||||
{
|
||||
return StaticCast<ISymbol>.From(this.GetMembers());
|
||||
}
|
||||
|
||||
ImmutableArray<ISymbol> INamespaceOrTypeSymbol.GetMembers(string name)
|
||||
{
|
||||
return StaticCast<ISymbol>.From(this.GetMembers(name));
|
||||
}
|
||||
|
||||
ImmutableArray<INamedTypeSymbol> INamespaceOrTypeSymbol.GetTypeMembers()
|
||||
{
|
||||
return StaticCast<INamedTypeSymbol>.From(this.GetTypeMembers());
|
||||
}
|
||||
|
||||
ImmutableArray<INamedTypeSymbol> INamespaceOrTypeSymbol.GetTypeMembers(string name)
|
||||
{
|
||||
return StaticCast<INamedTypeSymbol>.From(this.GetTypeMembers(name));
|
||||
}
|
||||
|
||||
ImmutableArray<INamedTypeSymbol> INamespaceOrTypeSymbol.GetTypeMembers(string name, int arity)
|
||||
{
|
||||
return StaticCast<INamedTypeSymbol>.From(this.GetTypeMembers(name, arity));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,292 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using Cci = Microsoft.Cci;
|
||||
|
||||
namespace Pchp.CodeAnalysis.Symbols
|
||||
{
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System;
|
||||
using Cci = Microsoft.Cci;
|
||||
/// <summary>
|
||||
/// Represents a namespace.
|
||||
/// </summary>
|
||||
internal abstract partial class NamespaceSymbol : NamespaceOrTypeSymbol, INamespaceSymbol
|
||||
{
|
||||
/// <summary>
|
||||
/// Get all the members of this symbol that are namespaces.
|
||||
/// </summary>
|
||||
/// <returns>An IEnumerable containing all the namespaces that are members of this symbol.
|
||||
/// If this symbol has no namespace members, returns an empty IEnumerable. Never returns
|
||||
/// null.</returns>
|
||||
public IEnumerable<NamespaceSymbol> GetNamespaceMembers()
|
||||
{
|
||||
return this.GetMembers().OfType<NamespaceSymbol>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this namespace is the unnamed, global namespace that is
|
||||
/// at the root of all namespaces.
|
||||
/// </summary>
|
||||
public virtual bool IsGlobalNamespace
|
||||
{
|
||||
get
|
||||
{
|
||||
return (object)ContainingNamespace == null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The kind of namespace: Module, Assembly or Compilation.
|
||||
/// Module namespaces contain only members from the containing module that share the same namespace name.
|
||||
/// Assembly namespaces contain members for all modules in the containing assembly that share the same namespace name.
|
||||
/// Compilation namespaces contain all members, from source or referenced metadata (assemblies and modules) that share the same namespace name.
|
||||
/// </summary>
|
||||
public virtual NamespaceKind NamespaceKind
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The containing compilation for compilation namespaces.
|
||||
/// </summary>
|
||||
public virtual PhpCompilation ContainingCompilation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.NamespaceKind == NamespaceKind.Compilation)
|
||||
throw new NotSupportedException();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If a namespace has Assembly or Compilation extent, it may be composed of multiple
|
||||
/// namespaces that are merged together. If so, ConstituentNamespaces returns
|
||||
/// all the namespaces that were merged. If this namespace was not merged, returns
|
||||
/// an array containing only this namespace.
|
||||
/// </summary>
|
||||
public virtual ImmutableArray<NamespaceSymbol> ConstituentNamespaces
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray.Create(this);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed override INamedTypeSymbol ContainingType => null;
|
||||
|
||||
/// <summary>
|
||||
/// Containing assembly.
|
||||
/// </summary>
|
||||
public abstract override IAssemblySymbol ContainingAssembly { get; }
|
||||
|
||||
internal override IModuleSymbol ContainingModule
|
||||
{
|
||||
get
|
||||
{
|
||||
if (NamespaceKind == NamespaceKind.Module)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the kind of this symbol.
|
||||
/// </summary>
|
||||
public sealed override SymbolKind Kind
|
||||
{
|
||||
get
|
||||
{
|
||||
return SymbolKind.Namespace;
|
||||
}
|
||||
}
|
||||
|
||||
public override sealed bool IsImplicitlyDeclared
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.IsGlobalNamespace;
|
||||
}
|
||||
}
|
||||
|
||||
// Only the compiler can create namespace symbols.
|
||||
internal NamespaceSymbol()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get this accessibility that was declared on this symbol. For symbols that do not have
|
||||
/// accessibility declared on them, returns NotApplicable.
|
||||
/// </summary>
|
||||
public sealed override Accessibility DeclaredAccessibility => Accessibility.Public;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this symbol is "static"; i.e., declared with the "static" modifier or
|
||||
/// implicitly static.
|
||||
/// </summary>
|
||||
public sealed override bool IsStatic => true;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this symbol was declared as requiring an override; i.e., declared with
|
||||
/// the "abstract" modifier. Also returns true on a type declared as "abstract", all
|
||||
/// interface types, and members of interface types.
|
||||
/// </summary>
|
||||
public sealed override bool IsAbstract => false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this symbol was declared to override a base class member and was also
|
||||
/// sealed from further overriding; i.e., declared with the "sealed" modifier. Also set for
|
||||
/// types that do not allow a derived class (declared with "sealed" or "static" or "struct"
|
||||
/// or "enum" or "delegate").
|
||||
/// </summary>
|
||||
public sealed override bool IsSealed => false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns data decoded from Obsolete attribute or null if there is no Obsolete attribute.
|
||||
/// This property returns ObsoleteAttributeData.Uninitialized if attribute arguments haven't been decoded yet.
|
||||
/// </summary>
|
||||
internal sealed override ObsoleteAttributeData ObsoleteAttributeData => null;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an implicit type symbol for this namespace or null if there is none. This type
|
||||
/// wraps misplaced global code.
|
||||
/// </summary>
|
||||
internal NamedTypeSymbol ImplicitType
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
//var types = this.GetTypeMembers(TypeSymbol.ImplicitTypeName);
|
||||
//if (types.Length == 0)
|
||||
//{
|
||||
// return null;
|
||||
//}
|
||||
|
||||
//Debug.Assert(types.Length == 1);
|
||||
//return types[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lookup a nested namespace.
|
||||
/// </summary>
|
||||
/// <param name="names">
|
||||
/// Sequence of names for nested child namespaces.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Symbol for the most nested namespace, if found. Nothing
|
||||
/// if namespace or any part of it can not be found.
|
||||
/// </returns>
|
||||
internal NamespaceSymbol LookupNestedNamespace(ImmutableArray<string> names)
|
||||
{
|
||||
NamespaceSymbol scope = this;
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
NamespaceSymbol nextScope = null;
|
||||
|
||||
foreach (NamespaceOrTypeSymbol symbol in scope.GetMembers(name))
|
||||
{
|
||||
var ns = symbol as NamespaceSymbol;
|
||||
|
||||
if ((object)ns != null)
|
||||
{
|
||||
if ((object)nextScope != null)
|
||||
{
|
||||
Debug.Assert((object)nextScope == null, "Why did we run into an unmerged namespace?");
|
||||
nextScope = null;
|
||||
break;
|
||||
}
|
||||
|
||||
nextScope = ns;
|
||||
}
|
||||
}
|
||||
|
||||
scope = nextScope;
|
||||
|
||||
if ((object)scope == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
internal NamespaceSymbol GetNestedNamespace(string name)
|
||||
{
|
||||
foreach (var sym in this.GetMembers(name))
|
||||
{
|
||||
if (sym.Kind == SymbolKind.Namespace)
|
||||
{
|
||||
return (NamespaceSymbol)sym;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#region INamespaceSymbol Members
|
||||
|
||||
IEnumerable<INamespaceOrTypeSymbol> INamespaceSymbol.GetMembers()
|
||||
{
|
||||
return this.GetMembers().OfType<INamespaceOrTypeSymbol>();
|
||||
}
|
||||
|
||||
IEnumerable<INamespaceOrTypeSymbol> INamespaceSymbol.GetMembers(string name)
|
||||
{
|
||||
return this.GetMembers(name).OfType<INamespaceOrTypeSymbol>();
|
||||
}
|
||||
|
||||
IEnumerable<INamespaceSymbol> INamespaceSymbol.GetNamespaceMembers()
|
||||
{
|
||||
return this.GetNamespaceMembers();
|
||||
}
|
||||
|
||||
NamespaceKind INamespaceSymbol.NamespaceKind
|
||||
{
|
||||
get { return this.NamespaceKind; }
|
||||
}
|
||||
|
||||
Compilation INamespaceSymbol.ContainingCompilation
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.ContainingCompilation;
|
||||
}
|
||||
}
|
||||
|
||||
ImmutableArray<INamespaceSymbol> INamespaceSymbol.ConstituentNamespaces
|
||||
{
|
||||
get
|
||||
{
|
||||
return StaticCast<INamespaceSymbol>.From(this.ConstituentNamespaces);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ISymbol Members
|
||||
|
||||
public override void Accept(SymbolVisitor visitor)
|
||||
{
|
||||
visitor.VisitNamespace(this);
|
||||
}
|
||||
|
||||
public override TResult Accept<TResult>(SymbolVisitor<TResult> visitor)
|
||||
{
|
||||
return visitor.VisitNamespace(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -23,6 +23,8 @@ namespace Pchp.CodeAnalysis.Symbols
|
|||
|
||||
public override Symbol ContainingSymbol => _sourceAssembly;
|
||||
|
||||
internal override IModuleSymbol ContainingModule => null;
|
||||
|
||||
public override Accessibility DeclaredAccessibility => Accessibility.NotApplicable;
|
||||
|
||||
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Pchp.Syntax;
|
||||
using Pchp.Syntax.AST;
|
||||
|
||||
namespace Pchp.CodeAnalysis.Symbols
|
||||
{
|
||||
internal sealed class SourceNamedTypeSymbol : NamedTypeSymbol
|
||||
{
|
||||
readonly TypeDecl _syntax;
|
||||
readonly SourceModuleSymbol _sourceModule;
|
||||
|
||||
public SourceNamedTypeSymbol(SourceModuleSymbol module, TypeDecl syntax)
|
||||
{
|
||||
_syntax = syntax;
|
||||
_sourceModule = module;
|
||||
}
|
||||
|
||||
internal override IModuleSymbol ContainingModule => _sourceModule;
|
||||
|
||||
public override Symbol ContainingSymbol => _sourceModule;
|
||||
|
||||
public override string Name => _syntax.Name.Value;
|
||||
|
||||
public override TypeKind TypeKind => TypeKind.Class;
|
||||
|
||||
public override Accessibility DeclaredAccessibility
|
||||
{
|
||||
get
|
||||
{
|
||||
return Accessibility.Public;
|
||||
}
|
||||
}
|
||||
|
||||
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray<SyntaxReference>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsAbstract => (_syntax.MemberAttributes & PhpMemberAttributes.Abstract) != 0;
|
||||
|
||||
public override bool IsSealed => (_syntax.MemberAttributes & PhpMemberAttributes.Final) != 0;
|
||||
|
||||
public override bool IsStatic => (_syntax.MemberAttributes & PhpMemberAttributes.Static) != 0;
|
||||
|
||||
public override SymbolKind Kind => SymbolKind.NamedType;
|
||||
|
||||
public override ImmutableArray<Location> Locations
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal override TypeLayout Layout => default(TypeLayout);
|
||||
|
||||
internal override ObsoleteAttributeData ObsoleteAttributeData
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override ImmutableArray<Symbol> GetMembers()
|
||||
{
|
||||
return ImmutableArray<Symbol>.Empty;
|
||||
}
|
||||
|
||||
public override ImmutableArray<Symbol> GetMembers(string name)
|
||||
{
|
||||
return ImmutableArray<Symbol>.Empty;
|
||||
}
|
||||
|
||||
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers()
|
||||
{
|
||||
return ImmutableArray<NamedTypeSymbol>.Empty;
|
||||
}
|
||||
|
||||
public override ImmutableArray<NamedTypeSymbol> GetTypeMembers(string name)
|
||||
{
|
||||
return ImmutableArray<NamedTypeSymbol>.Empty;
|
||||
}
|
||||
|
||||
internal override IEnumerable<IFieldSymbol> GetFieldsToEmit()
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
internal override ImmutableArray<NamedTypeSymbol> GetInterfacesToEmit()
|
||||
{
|
||||
return ImmutableArray<NamedTypeSymbol>.Empty;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -941,7 +941,8 @@ namespace Pchp.CodeAnalysis
|
|||
|
||||
public string ToDisplayString(SymbolDisplayFormat format = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return this.Name;
|
||||
//throw new NotImplementedException();
|
||||
//return SymbolDisplay.ToDisplayString(this, format);
|
||||
}
|
||||
|
||||
|
@ -1160,12 +1161,12 @@ namespace Pchp.CodeAnalysis
|
|||
return ImmutableArray<AttributeData>.Empty; // StaticCast<AttributeData>.From(this.GetAttributes());
|
||||
}
|
||||
|
||||
public void Accept(SymbolVisitor visitor)
|
||||
public virtual void Accept(SymbolVisitor visitor)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public TResult Accept<TResult>(SymbolVisitor<TResult> visitor)
|
||||
public virtual TResult Accept<TResult>(SymbolVisitor<TResult> visitor)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using Roslyn.Utilities;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Pchp.CodeAnalysis.Symbols
|
||||
{
|
||||
/// <summary>
|
||||
/// A TypeSymbol is a base class for all the symbols that represent a type in PHP.
|
||||
/// </summary>
|
||||
internal abstract partial class TypeSymbol : NamespaceOrTypeSymbol, ITypeSymbol
|
||||
{
|
||||
public virtual ImmutableArray<INamedTypeSymbol> AllInterfaces
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray<INamedTypeSymbol>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual INamedTypeSymbol BaseType
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ImmutableArray<INamedTypeSymbol> Interfaces
|
||||
{
|
||||
get
|
||||
{
|
||||
return ImmutableArray<INamedTypeSymbol>.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsAnonymousType => false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this type is known to be a reference type. It is never the case that
|
||||
/// IsReferenceType and IsValueType both return true. However, for an unconstrained type
|
||||
/// parameter, IsReferenceType and IsValueType will both return false.
|
||||
/// </summary>
|
||||
public virtual bool IsReferenceType
|
||||
{
|
||||
get
|
||||
{
|
||||
var kind = TypeKind;
|
||||
return kind != TypeKind.Enum && kind != TypeKind.Struct && kind != TypeKind.Error;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this type is known to be a value type. It is never the case that
|
||||
/// IsReferenceType and IsValueType both return true. However, for an unconstrained type
|
||||
/// parameter, IsReferenceType and IsValueType will both return false.
|
||||
/// </summary>
|
||||
public virtual bool IsValueType
|
||||
{
|
||||
get
|
||||
{
|
||||
var kind = TypeKind;
|
||||
return kind == TypeKind.Struct || kind == TypeKind.Enum;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual SpecialType SpecialType => SpecialType.None;
|
||||
|
||||
public virtual TypeKind TypeKind
|
||||
{
|
||||
get
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
ITypeSymbol ITypeSymbol.OriginalDefinition
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ITypeSymbol)this.OriginalDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
public ISymbol FindImplementationForInterfaceMember(ISymbol interfaceMember)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче