- SourceFunctionSymbol
- SourceMethodSymbol
This commit is contained in:
Jakub Míšek 2016-02-16 13:41:41 +01:00
Родитель 722e7195d9
Коммит 6023f9a65b
10 изменённых файлов: 1028 добавлений и 16 удалений

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

@ -0,0 +1,624 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.Emit;
using Roslyn.Utilities;
using Cci = Microsoft.Cci;
using Pchp.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis;
namespace Pchp.CodeAnalysis.Symbols
{
internal partial class MethodSymbol :
Cci.ITypeMemberReference,
Cci.IMethodReference,
Cci.IGenericMethodInstanceReference,
Cci.ISpecializedMethodReference,
Cci.ITypeDefinitionMember,
Cci.IMethodDefinition
{
Cci.IGenericMethodInstanceReference Cci.IMethodReference.AsGenericMethodInstanceReference
{
get
{
Debug.Assert(this.IsDefinitionOrDistinct());
if (!this.IsDefinition &&
this.IsGenericMethod)
{
return this;
}
return null;
}
}
Cci.ISpecializedMethodReference Cci.IMethodReference.AsSpecializedMethodReference
{
get
{
Debug.Assert(this.IsDefinitionOrDistinct());
if (!this.IsDefinition &&
(!this.IsGenericMethod || PEModuleBuilder.IsGenericType(this.ContainingType)))
{
Debug.Assert((object)this.ContainingType != null && PEModuleBuilder.IsGenericType(this.ContainingType));
return this;
}
return null;
}
}
Cci.IDefinition Cci.IReference.AsDefinition(EmitContext context)
{
return ResolvedMethodImpl(context);
}
Cci.ITypeReference Cci.ITypeMemberReference.GetContainingType(EmitContext context)
{
Debug.Assert(this.IsDefinitionOrDistinct());
//var synthesizedGlobalMethod = this as SynthesizedGlobalMethodSymbol;
//if ((object)synthesizedGlobalMethod != null)
//{
// return synthesizedGlobalMethod.ContainingPrivateImplementationDetailsType;
//}
return (Cci.ITypeReference)this.ContainingType;
}
void Cci.IReference.Dispatch(Cci.MetadataVisitor visitor)
{
Debug.Assert(this.IsDefinitionOrDistinct());
if (!this.IsDefinition)
{
if (this.IsGenericMethod)
{
Debug.Assert(((Cci.IMethodReference)this).AsGenericMethodInstanceReference != null);
visitor.Visit((Cci.IGenericMethodInstanceReference)this);
}
else
{
Debug.Assert(((Cci.IMethodReference)this).AsSpecializedMethodReference != null);
visitor.Visit((Cci.ISpecializedMethodReference)this);
}
}
else
{
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)visitor.Context.Module;
if (this.ContainingModule == moduleBeingBuilt.SourceModule)
{
Debug.Assert(((Cci.IMethodReference)this).GetResolvedMethod(visitor.Context) != null);
visitor.Visit((Cci.IMethodDefinition)this);
}
else
{
visitor.Visit((Cci.IMethodReference)this);
}
}
}
string Cci.INamedEntity.Name
{
get { return this.MetadataName; }
}
bool Cci.IMethodReference.AcceptsExtraArguments
{
get
{
return this.IsVararg;
}
}
ushort Cci.IMethodReference.GenericParameterCount
{
get
{
return (ushort)this.Arity;
}
}
bool Cci.IMethodReference.IsGeneric
{
get
{
return this.IsGenericMethod;
}
}
ushort Cci.ISignature.ParameterCount
{
get
{
return (ushort)this.Parameters.Length;
}
}
Cci.IMethodDefinition Cci.IMethodReference.GetResolvedMethod(EmitContext context)
{
return ResolvedMethodImpl(context);
}
private Cci.IMethodDefinition ResolvedMethodImpl(EmitContext context)
{
Debug.Assert(this.IsDefinitionOrDistinct());
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
if (this.IsDefinition && // can't be generic instantiation
this.ContainingModule == moduleBeingBuilt.SourceModule) // must be declared in the module we are building
{
Debug.Assert((object)this.PartialDefinitionPart == null); // must be definition
return this;
}
return null;
}
ImmutableArray<Cci.IParameterTypeInformation> Cci.IMethodReference.ExtraParameters
{
get
{
return ImmutableArray<Cci.IParameterTypeInformation>.Empty;
}
}
public virtual Cci.CallingConvention CallingConvention => Cci.CallingConvention.Default;
ImmutableArray<Cci.IParameterTypeInformation> Cci.ISignature.GetParameters(EmitContext context)
{
Debug.Assert(this.IsDefinitionOrDistinct());
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
if (this.IsDefinition && this.ContainingModule == moduleBeingBuilt.SourceModule)
{
return StaticCast<Cci.IParameterTypeInformation>.From(this.EnumerateDefinitionParameters());
}
else
{
throw new NotImplementedException();
//return moduleBeingBuilt.Translate(this.Parameters);
}
}
private ImmutableArray<Cci.IParameterDefinition> EnumerateDefinitionParameters()
{
Debug.Assert(this.Parameters.All(p => p.IsDefinition));
return this.Parameters.Cast<Cci.IParameterDefinition>().ToImmutableArray();
}
ImmutableArray<Cci.ICustomModifier> Cci.ISignature.ReturnValueCustomModifiers
{
get
{
return this.ReturnTypeCustomModifiers.As<Cci.ICustomModifier>();
}
}
public virtual bool ReturnValueIsByRef
{
get
{
//return this.ReturnType is ByRefReturnErrorTypeSymbol;
return false;
}
}
Cci.ITypeReference Cci.ISignature.GetType(EmitContext context)
{
return (Cci.ITypeReference)this.ReturnType;
}
IEnumerable<Cci.ITypeReference> Cci.IGenericMethodInstanceReference.GetGenericArguments(EmitContext context)
{
PEModuleBuilder moduleBeingBuilt = (PEModuleBuilder)context.Module;
Debug.Assert(((Cci.IMethodReference)this).AsGenericMethodInstanceReference != null);
foreach (var arg in this.TypeArguments)
{
throw new NotImplementedException();
//yield return moduleBeingBuilt.Translate(arg,
// syntaxNodeOpt: (CSharpSyntaxNode)context.SyntaxNodeOpt,
// diagnostics: context.Diagnostics);
}
yield break;
}
Cci.IMethodReference Cci.IGenericMethodInstanceReference.GetGenericMethod(EmitContext context)
{
Debug.Assert(((Cci.IMethodReference)this).AsGenericMethodInstanceReference != null);
if (!PEModuleBuilder.IsGenericType(this.ContainingType))
{
// NoPia method might come through here.
return ((PEModuleBuilder)context.Module).Translate((MethodSymbol)this.OriginalDefinition, context.Diagnostics, true);
}
throw new NotImplementedException();
}
Cci.IMethodReference Cci.ISpecializedMethodReference.UnspecializedVersion
{
get
{
Debug.Assert(((Cci.IMethodReference)this).AsSpecializedMethodReference != null);
return (MethodSymbol)this.OriginalDefinition;
}
}
Cci.ITypeDefinition Cci.ITypeDefinitionMember.ContainingTypeDefinition
{
get
{
CheckDefinitionInvariant();
//var synthesizedGlobalMethod = this as SynthesizedGlobalMethodSymbol;
//if ((object)synthesizedGlobalMethod != null)
//{
// return synthesizedGlobalMethod.ContainingPrivateImplementationDetailsType;
//}
return (Cci.ITypeDefinition)this.ContainingType;
}
}
Cci.TypeMemberVisibility Cci.ITypeDefinitionMember.Visibility
{
get
{
CheckDefinitionInvariant();
return PEModuleBuilder.MemberVisibility(this);
}
}
Cci.IMethodBody Cci.IMethodDefinition.GetBody(EmitContext context)
{
CheckDefinitionInvariant();
return ((PEModuleBuilder)context.Module).GetMethodBody(this);
}
IEnumerable<Cci.IGenericMethodParameter> Cci.IMethodDefinition.GenericParameters
{
get
{
CheckDefinitionInvariant();
Debug.Assert(this.TypeParameters.All(p => p.IsDefinition));
return this.TypeParameters.Cast<Cci.IGenericMethodParameter>();
}
}
bool Cci.IMethodDefinition.HasDeclarativeSecurity
{
get
{
CheckDefinitionInvariant();
return false;
}
}
IEnumerable<Cci.SecurityAttribute> Cci.IMethodDefinition.SecurityAttributes
{
get
{
CheckDefinitionInvariant();
yield break;
}
}
bool Cci.IMethodDefinition.IsAbstract
{
get
{
CheckDefinitionInvariant();
return this.IsAbstract;
}
}
bool Cci.IMethodDefinition.IsAccessCheckedOnOverride
{
get
{
CheckDefinitionInvariant();
return this.IsAccessCheckedOnOverride;
}
}
internal virtual bool IsAccessCheckedOnOverride
{
get
{
CheckDefinitionInvariant();
// Enforce C#'s notion of internal virtual
// If the method is private or internal and virtual but not final
// Set the new bit to indicate that it can only be overridden
// by classes that can normally access this member.
Accessibility accessibility = this.DeclaredAccessibility;
return (accessibility == Accessibility.Private ||
accessibility == Accessibility.ProtectedAndInternal ||
accessibility == Accessibility.Internal)
&& ((Cci.IMethodDefinition)this).IsVirtual && !((Cci.IMethodDefinition)this).IsSealed;
}
}
bool Cci.IMethodDefinition.IsConstructor
{
get
{
CheckDefinitionInvariant();
return this.MethodKind == MethodKind.Constructor;
}
}
bool Cci.IMethodDefinition.IsExternal
{
get
{
CheckDefinitionInvariant();
return this.IsExternal;
}
}
internal virtual bool IsExternal
{
get
{
CheckDefinitionInvariant();
// Delegate methods are implemented by the runtime.
// Note that we don't force methods marked with MethodImplAttributes.InternalCall or MethodImplAttributes.Runtime
// to be external, so it is possible to mark methods with bodies by these flags. It's up to the VM to interpret these flags
// and throw runtime exception if they are applied incorrectly.
return this.IsExtern || (object)ContainingType != null && ContainingType.TypeKind == TypeKind.Delegate;
}
}
bool Cci.IMethodDefinition.IsHiddenBySignature
{
get
{
CheckDefinitionInvariant();
return !this.HidesBaseMethodsByName;
}
}
bool Cci.IMethodDefinition.IsNewSlot
{
get
{
CheckDefinitionInvariant();
return this.IsMetadataNewSlot();
}
}
/// <summary>
/// This method indicates whether or not the runtime will regard the method
/// as newslot (as indicated by the presence of the "newslot" modifier in the
/// signature).
/// WARN WARN WARN: We won't have a final value for this until declaration
/// diagnostics have been computed for all <see cref="SourceMemberContainerTypeSymbol"/>s, so pass
/// ignoringInterfaceImplementationChanges: true if you need a value sooner
/// and aren't concerned about tweaks made to satisfy interface implementation
/// requirements.
/// NOTE: Not ignoring changes can only result in a value that is more true.
/// </summary>
internal abstract bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false);
bool Cci.IMethodDefinition.IsPlatformInvoke
{
get
{
CheckDefinitionInvariant();
return this.GetDllImportData() != null;
}
}
Cci.IPlatformInvokeInformation Cci.IMethodDefinition.PlatformInvokeData
{
get
{
CheckDefinitionInvariant();
return this.GetDllImportData();
}
}
public virtual System.Reflection.MethodImplAttributes GetImplementationAttributes(EmitContext context)
{
CheckDefinitionInvariant();
return System.Reflection.MethodImplAttributes.IL;
}
bool Cci.IMethodDefinition.IsRuntimeSpecial
{
get
{
CheckDefinitionInvariant();
return this.HasRuntimeSpecialName;
}
}
internal virtual bool HasRuntimeSpecialName
{
get
{
CheckDefinitionInvariant();
return this.MethodKind == MethodKind.Constructor
|| this.MethodKind == MethodKind.StaticConstructor;
}
}
bool Cci.IMethodDefinition.IsSealed
{
get
{
CheckDefinitionInvariant();
return this.IsMetadataFinal;
}
}
internal virtual bool IsMetadataFinal
{
get
{
// destructors should override this behavior
Debug.Assert(this.MethodKind != MethodKind.Destructor);
return this.IsSealed ||
(this.IsMetadataVirtual() &&
!(this.IsVirtual || this.IsOverride || this.IsAbstract || this.MethodKind == MethodKind.Destructor));
}
}
public virtual bool IsSpecialName
{
get
{
CheckDefinitionInvariant();
return false;
}
}
bool Cci.IMethodDefinition.IsStatic
{
get
{
CheckDefinitionInvariant();
return this.IsStatic;
}
}
bool Cci.IMethodDefinition.IsVirtual
{
get
{
CheckDefinitionInvariant();
return this.IsMetadataVirtual();
}
}
/// <summary>
/// This method indicates whether or not the runtime will regard the method
/// as virtual (as indicated by the presence of the "virtual" modifier in the
/// signature).
/// WARN WARN WARN: We won't have a final value for this until declaration
/// diagnostics have been computed for all <see cref="SourceMemberContainerTypeSymbol"/>s, so pass
/// ignoringInterfaceImplementationChanges: true if you need a value sooner
/// and aren't concerned about tweaks made to satisfy interface implementation
/// requirements.
/// NOTE: Not ignoring changes can only result in a value that is more true.
/// </summary>
internal abstract bool IsMetadataVirtual(bool ignoreInterfaceImplementationChanges = false);
ImmutableArray<Cci.IParameterDefinition> Cci.IMethodDefinition.Parameters
{
get
{
CheckDefinitionInvariant();
return EnumerateDefinitionParameters();
}
}
public bool RequiresSecurityObject
{
get
{
CheckDefinitionInvariant();
return false;
}
}
IEnumerable<Cci.ICustomAttribute> Cci.IMethodDefinition.ReturnValueAttributes
{
get
{
return GetReturnValueCustomAttributesToEmit().Cast<Cci.ICustomAttribute>();
}
}
private IEnumerable<AttributeData> GetReturnValueCustomAttributesToEmit()
{
CheckDefinitionInvariant();
//ImmutableArray<CSharpAttributeData> userDefined;
//ArrayBuilder<SynthesizedAttributeData> synthesized = null;
//userDefined = this.GetReturnTypeAttributes();
//this.AddSynthesizedReturnTypeAttributes(ref synthesized);
//if (userDefined.IsEmpty && synthesized == null)
//{
// return SpecializedCollections.EmptyEnumerable<CSharpAttributeData>();
//}
//// Note that callers of this method (CCI and ReflectionEmitter) have to enumerate
//// all items of the returned iterator, otherwise the synthesized ArrayBuilder may leak.
//return GetCustomAttributesToEmit(userDefined, synthesized, isReturnType: true, emittingAssemblyAttributesInNetModule: false);
yield break;
}
bool Cci.IMethodDefinition.ReturnValueIsMarshalledExplicitly
{
get
{
CheckDefinitionInvariant();
return this.ReturnValueIsMarshalledExplicitly;
}
}
internal virtual bool ReturnValueIsMarshalledExplicitly
{
get
{
//CheckDefinitionInvariant();
//return this.ReturnValueMarshallingInformation != null;
return false;
}
}
Cci.IMarshallingInformation Cci.IMethodDefinition.ReturnValueMarshallingInformation
{
get
{
CheckDefinitionInvariant();
return null;
}
}
ImmutableArray<byte> Cci.IMethodDefinition.ReturnValueMarshallingDescriptor
{
get
{
CheckDefinitionInvariant();
return this.ReturnValueMarshallingDescriptor;
}
}
internal virtual ImmutableArray<byte> ReturnValueMarshallingDescriptor
{
get
{
CheckDefinitionInvariant();
return default(ImmutableArray<byte>);
}
}
Cci.INamespace Cci.IMethodDefinition.ContainingNamespace
{
get
{
return (Cci.INamespace)ContainingNamespace;
}
}
}
}

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

@ -640,6 +640,11 @@ namespace Pchp.CodeAnalysis.Emit
throw new NotImplementedException();
}
internal ImmutableArray<Cci.IParameterTypeInformation> Translate(ImmutableArray<IParameterSymbol> @params)
{
return @params.Cast<Cci.IParameterTypeInformation>().ToImmutableArray();
}
Cci.IAssemblyReference Cci.IModuleReference.GetContainingAssembly(EmitContext context)
{
throw new NotImplementedException();
@ -649,5 +654,20 @@ namespace Pchp.CodeAnalysis.Emit
{
return (object)method.ContainingModule == _sourceModule && method.IsDefinition;
}
public static bool IsGenericType(INamedTypeSymbol toCheck)
{
while ((object)toCheck != null)
{
if (toCheck.Arity > 0)
{
return true;
}
toCheck = toCheck.ContainingType;
}
return false;
}
}
}

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

@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Emit;
using Pchp.CodeAnalysis.Symbols;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
@ -19,13 +20,13 @@ namespace Pchp.CodeAnalysis
[Conditional("DEBUG")]
internal protected void CheckDefinitionInvariant()
{
//// can't be generic instantiation
//Debug.Assert(this.IsDefinition);
// can't be generic instantiation
Debug.Assert(this.IsDefinition);
//// must be declared in the module we are building
//Debug.Assert(this.ContainingModule is SourceModuleSymbol ||
// (this.Kind == SymbolKind.Assembly && this is SourceAssemblySymbol) ||
// (this.Kind == SymbolKind.NetModule && this is SourceModuleSymbol));
// must be declared in the module we are building
Debug.Assert(this.ContainingModule is SourceModuleSymbol ||
(this.Kind == SymbolKind.Assembly && this is SourceAssemblySymbol) ||
(this.Kind == SymbolKind.NetModule && this is SourceModuleSymbol));
}
/// <summary>

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

@ -57,6 +57,7 @@
<Compile Include="Compilation\PhpCompilationOptions.cs" />
<Compile Include="Compilation\ReferenceManager.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Emitter\Model\MethodSymbolAdapter.cs" />
<Compile Include="Emitter\Model\NamedTypeSymbolAdapter.cs" />
<Compile Include="Emitter\Model\NamespaceSymbolAdapter.cs" />
<Compile Include="Emitter\Model\PEAssemblyBuilder.cs" />
@ -71,11 +72,14 @@
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Symbols\AssemblySymbol.cs" />
<Compile Include="Symbols\MethodSymbol.cs" />
<Compile Include="Symbols\NamedTypeSymbol.cs" />
<Compile Include="Symbols\NamespaceOrTypeSymbol.cs" />
<Compile Include="Symbols\NamespaceSymbol.cs" />
<Compile Include="Symbols\Source\MemberAttributesAdapter.cs" />
<Compile Include="Symbols\Source\SourceAssemblySymbol.cs" />
<Compile Include="Symbols\Source\SourceFunctionSymbol.cs" />
<Compile Include="Symbols\Source\SourceMethodSymbol.cs" />
<Compile Include="Symbols\Source\SourceModuleSymbol.cs" />
<Compile Include="Symbols\Source\SourceNamedTypeSymbol.cs" />
<Compile Include="Symbols\Source\SourceNamespaceSymbol.cs" />

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

@ -0,0 +1,144 @@
using Microsoft.CodeAnalysis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Immutable;
namespace Pchp.CodeAnalysis.Symbols
{
/// <summary>
/// Represents a method or method-like symbol (including constructor,
/// destructor, operator, or property/event accessor).
/// </summary>
internal abstract partial class MethodSymbol : Symbol, IMethodSymbol
{
public virtual int Arity => 0;
public INamedTypeSymbol AssociatedAnonymousDelegate
{
get
{
throw new NotImplementedException();
}
}
public ISymbol AssociatedSymbol
{
get
{
throw new NotImplementedException();
}
}
public IMethodSymbol ConstructedFrom
{
get
{
throw new NotImplementedException();
}
}
public ImmutableArray<IMethodSymbol> ExplicitInterfaceImplementations
{
get
{
throw new NotImplementedException();
}
}
public bool HidesBaseMethodsByName
{
get
{
throw new NotImplementedException();
}
}
public virtual bool IsAsync => false;
public virtual bool IsCheckedBuiltin
{
get
{
throw new NotImplementedException();
}
}
public virtual bool IsExtensionMethod => false;
public virtual bool IsGenericMethod => false;
public virtual bool IsVararg => false;
public abstract MethodKind MethodKind { get; }
public virtual IMethodSymbol OverriddenMethod => null;
public abstract ImmutableArray<IParameterSymbol> Parameters { get; }
public IMethodSymbol PartialDefinitionPart => null;
public IMethodSymbol PartialImplementationPart => null;
public ITypeSymbol ReceiverType
{
get
{
throw new NotImplementedException();
}
}
public IMethodSymbol ReducedFrom
{
get
{
throw new NotImplementedException();
}
}
public abstract bool ReturnsVoid { get; }
public abstract ITypeSymbol ReturnType { get; }
public virtual ImmutableArray<CustomModifier> ReturnTypeCustomModifiers => ImmutableArray<CustomModifier>.Empty;
public virtual ImmutableArray<ITypeSymbol> TypeArguments => ImmutableArray<ITypeSymbol>.Empty;
public virtual ImmutableArray<ITypeParameterSymbol> TypeParameters => ImmutableArray<ITypeParameterSymbol>.Empty;
IMethodSymbol IMethodSymbol.OriginalDefinition
{
get
{
throw new NotImplementedException();
}
}
public IMethodSymbol Construct(params ITypeSymbol[] typeArguments)
{
throw new NotImplementedException();
}
public DllImportData GetDllImportData()
{
throw new NotImplementedException();
}
public ImmutableArray<AttributeData> GetReturnTypeAttributes()
{
throw new NotImplementedException();
}
public ITypeSymbol GetTypeInferredDuringReduction(ITypeParameterSymbol reducedFromTypeParameter)
{
throw new NotImplementedException();
}
public IMethodSymbol ReduceExtensionMethod(ITypeSymbol receiverType)
{
throw new NotImplementedException();
}
}
}

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

@ -0,0 +1,97 @@
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.AST;
namespace Pchp.CodeAnalysis.Symbols
{
/// <summary>
/// Represents a global PHP function.
/// </summary>
internal sealed class SourceFunctionSymbol : MethodSymbol
{
readonly PhpCompilation/*!*/_compilation;
readonly FunctionDecl/*!*/_syntax;
public SourceFunctionSymbol(PhpCompilation/*!*/compilation, FunctionDecl/*!*/syntax)
{
Contract.ThrowIfNull(compilation);
Contract.ThrowIfNull(syntax);
_compilation = compilation;
_syntax = syntax;
}
public override string Name => NameUtils.MakeQualifiedName(_syntax.Name, _syntax.Namespace).ClrName();
public override Symbol ContainingSymbol => _compilation.SourceModule;
public override Accessibility DeclaredAccessibility => Accessibility.Public;
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
{
get
{
throw new NotImplementedException();
}
}
public override bool IsAbstract => false;
public override bool IsExtern => false;
public override bool IsOverride => false;
public override bool IsSealed => true;
public override bool IsStatic => true;
public override bool IsVirtual => false;
public override SymbolKind Kind => SymbolKind.Method;
public override ImmutableArray<Location> Locations
{
get
{
throw new NotImplementedException();
}
}
public override MethodKind MethodKind => MethodKind.Ordinary;
public override ImmutableArray<IParameterSymbol> Parameters
{
get
{
throw new NotImplementedException();
}
}
public override bool ReturnsVoid
{
get
{
throw new NotImplementedException();
}
}
public override ITypeSymbol ReturnType
{
get
{
throw new NotImplementedException();
}
}
internal override ObsoleteAttributeData ObsoleteAttributeData => null; // TODO: from PHPDoc
internal override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false) => false;
internal override bool IsMetadataVirtual(bool ignoreInterfaceImplementationChanges = false) => false;
}
}

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

@ -0,0 +1,109 @@
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.AST;
namespace Pchp.CodeAnalysis.Symbols
{
/// <summary>
/// Represents a PHP class method.
/// </summary>
internal sealed class SourceMethodSymbol : MethodSymbol
{
readonly NamedTypeSymbol _type;
readonly MethodDecl/*!*/_syntax;
public SourceMethodSymbol(NamedTypeSymbol/*!*/type, MethodDecl/*!*/syntax)
{
Contract.ThrowIfNull(type);
Contract.ThrowIfNull(syntax);
_type = type;
_syntax = syntax;
}
public override Symbol ContainingSymbol => _type;
public override Accessibility DeclaredAccessibility => _syntax.Modifiers.GetAccessibility();
public override ImmutableArray<SyntaxReference> DeclaringSyntaxReferences
{
get
{
throw new NotImplementedException();
}
}
public override bool IsAbstract => _syntax.Modifiers.IsAbstract();
public override bool IsExtern => false;
public override bool IsOverride
{
get
{
throw new NotImplementedException();
}
}
public override bool IsSealed => _syntax.Modifiers.IsSealed();
public override bool IsStatic => _syntax.Modifiers.IsStatic();
public override bool IsVirtual => !IsSealed && !_type.IsSealed && !IsStatic;
public override SymbolKind Kind => SymbolKind.Method;
public override ImmutableArray<Location> Locations
{
get
{
throw new NotImplementedException();
}
}
public override MethodKind MethodKind
{
get
{
// TODO: ctor, dtor, props, magic, ...
return MethodKind.Ordinary;
}
}
public override ImmutableArray<IParameterSymbol> Parameters
{
get
{
throw new NotImplementedException();
}
}
public override bool ReturnsVoid
{
get
{
throw new NotImplementedException();
}
}
public override ITypeSymbol ReturnType
{
get
{
throw new NotImplementedException();
}
}
internal override ObsoleteAttributeData ObsoleteAttributeData => null; // TODO: from PHPDoc
internal override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false) => false;
internal override bool IsMetadataVirtual(bool ignoreInterfaceImplementationChanges = false) => false;
}
}

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

@ -13,17 +13,30 @@ namespace Pchp.CodeAnalysis.Symbols
internal sealed class SourceNamedTypeSymbol : NamedTypeSymbol
{
readonly TypeDecl _syntax;
readonly SourceModuleSymbol _module;
readonly PhpCompilation _compilation;
public SourceNamedTypeSymbol(SourceModuleSymbol module, TypeDecl syntax)
readonly ImmutableArray<SourceMethodSymbol> _methods;
public SourceNamedTypeSymbol(PhpCompilation compilation, TypeDecl syntax)
{
_syntax = syntax;
_module = module;
_compilation = compilation;
_methods = GenerateMethods().ToImmutableArray();
}
internal override IModuleSymbol ContainingModule => _module;
IEnumerable<SourceMethodSymbol> GenerateMethods()
{
foreach (var m in _syntax.Members.OfType<MethodDecl>())
{
yield return new SourceMethodSymbol(this, m);
}
}
public override Symbol ContainingSymbol => _module;
internal override IModuleSymbol ContainingModule => _compilation.SourceModule;
public override Symbol ContainingSymbol => _compilation.SourceModule;
internal override PhpCompilation DeclaringCompilation => _compilation;
public override string Name => _syntax.Name.Value;
@ -70,7 +83,7 @@ namespace Pchp.CodeAnalysis.Symbols
public override ImmutableArray<Symbol> GetMembers()
{
return ImmutableArray<Symbol>.Empty;
return StaticCast<Symbol>.From(_methods); // TODO: + props, constants
}
public override ImmutableArray<Symbol> GetMembers(string name)

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

@ -42,12 +42,12 @@ namespace Pchp.CodeAnalysis.Symbols
public override void VisitFunctionDecl(FunctionDecl x)
{
// _tables._functions.Add ...
_tables._functions.Add(NameUtils.MakeQualifiedName(x.Name, x.Namespace), new SourceFunctionSymbol(_compilation, x));
}
public override void VisitTypeDecl(TypeDecl x)
{
_tables._types.Add(x.MakeQualifiedName(), new SourceNamedTypeSymbol(_compilation.SourceModule, x));
_tables._types.Add(x.MakeQualifiedName(), new SourceNamedTypeSymbol(_compilation, x));
}
}

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

@ -95,13 +95,13 @@ namespace Pchp.CodeAnalysis
/// Gets the nearest enclosing namespace for this namespace or type. For a nested type,
/// returns the namespace that contains its container.
/// </summary>
public virtual INamespaceSymbol ContainingNamespace
public virtual NamespaceSymbol ContainingNamespace
{
get
{
for (var container = this.ContainingSymbol; (object)container != null; container = container.ContainingSymbol)
{
var ns = container as INamespaceSymbol;
var ns = container as NamespaceSymbol;
if ((object)ns != null)
{
return ns;