- NamedTypeSymbol
- TypeSymbol
- NamespaceSymbol
- SourceModuleSymbol
- temporary use of SourceUnit
This commit is contained in:
Jakub Míšek 2016-02-15 18:03:49 +01:00
Родитель f382876b3f
Коммит 4f2fa1fd56
15 изменённых файлов: 1972 добавлений и 23 удалений

Просмотреть файл

@ -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();
}
}
}