MethodSymbol
- SourceFunctionSymbol - SourceMethodSymbol
This commit is contained in:
Родитель
722e7195d9
Коммит
6023f9a65b
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче