Exemplo n.º 1
0
        private static void ReportBadNotNullMemberIfNeeded(
            TypeSymbol type,
            DecodeWellKnownAttributeArguments <
                AttributeSyntax,
                CSharpAttributeData,
                AttributeLocation
                > arguments,
            string memberName
            )
        {
            foreach (Symbol foundMember in type.GetMembers(memberName))
            {
                if (foundMember.Kind == SymbolKind.Field || foundMember.Kind == SymbolKind.Property)
                {
                    return;
                }
            }

            Debug.Assert(arguments.AttributeSyntaxOpt is object);
            ((BindingDiagnosticBag)arguments.Diagnostics).Add(
                ErrorCode.WRN_MemberNotNullBadMember,
                arguments.AttributeSyntaxOpt.Location,
                memberName
                );
        }
Exemplo n.º 2
0
        private MethodSymbol DelegateConstructor(SyntaxNode syntax, TypeSymbol delegateType)
        {
            foreach (var possibleCtor in delegateType.GetMembers(WellKnownMemberNames.InstanceConstructorName))
            {
                var m = possibleCtor as MethodSymbol;
                if ((object)m == null)
                {
                    continue;
                }
                var parameters = m.Parameters;
                if (parameters.Length != 2)
                {
                    continue;
                }
                if (parameters[0].Type.SpecialType != SpecialType.System_Object)
                {
                    continue;
                }
                var p1t = parameters[1].Type.SpecialType;
                if (p1t == SpecialType.System_IntPtr || p1t == SpecialType.System_UIntPtr)
                {
                    return(m);
                }
            }

            // The delegate '{0}' does not have a valid constructor
            _diagnostics.Add(ErrorCode.ERR_BadDelegateConstructor, syntax.Location, delegateType);
            return(null);
        }
Exemplo n.º 3
0
        private static FieldSymbol FindFieldBySignature(
            TypeSymbol targetTypeSymbol,
            string targetMemberName,
            ImmutableArray <ModifierInfo <TypeSymbol> > customModifiers,
            TypeSymbol type
            )
        {
            foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName))
            {
                var field = member as FieldSymbol;
                TypeWithAnnotations fieldType;

                if (
                    (object)field != null &&
                    TypeSymbol.Equals(
                        (fieldType = field.TypeWithAnnotations).Type,
                        type,
                        TypeCompareKind.CLRSignatureCompareOptions
                        ) &&
                    CustomModifiersMatch(fieldType.CustomModifiers, customModifiers)
                    )
                {
                    // Behavior in the face of multiple matching signatures is
                    // implementation defined - we'll just pick the first one.
                    return(field);
                }
            }

            return(null);
        }
Exemplo n.º 4
0
        private static MethodSymbol FindMethodBySignature(
            TypeSymbol targetTypeSymbol,
            string targetMemberName,
            SignatureHeader targetMemberSignatureHeader,
            int targetMemberTypeParamCount,
            ParamInfo <TypeSymbol>[] targetParamInfo
            )
        {
            foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName))
            {
                var method = member as MethodSymbol;
                if (
                    (object)method != null &&
                    ((byte)method.CallingConvention == targetMemberSignatureHeader.RawValue) &&
                    (targetMemberTypeParamCount == method.Arity) &&
                    MethodSymbolMatchesParamInfo(method, targetParamInfo)
                    )
                {
                    // Behavior in the face of multiple matching signatures is
                    // implementation defined - we'll just pick the first one.
                    return(method);
                }
            }

            return(null);
        }
Exemplo n.º 5
0
 public void CheckTypes(TypeSymbol a, TypeSymbol b)
 {
     Assert.Equal(a.Name, b.Name);
     CheckSymbols(a.BaseType(), b.BaseType(), false);
     CheckSymbols(a.Interfaces(), b.Interfaces(), false);
     CheckSymbols(a.GetMembers(), b.GetMembers(), true);
 }
Exemplo n.º 6
0
        public override OutputFileAbstraction GetAbstraction()
        {
            //If external
            if (this.HasCustomMap)
            {
                return(null);
            }

            var result = new EnumAbstraction
            {
                Path   = AbstractPath,
                Name   = TypeSymbol.Name,
                Values = TypeSymbol
                         .GetMembers()
                         .Where(m => m.Kind == SymbolKind.Field)
                         .Select(m => m as IFieldSymbol)
                         .Select(f => new EnumValueAbstraction
                {
                    Name  = f.Name,
                    Value = (int)f.ConstantValue
                }).ToList()
            };


            return(result);
        }
        private MethodSymbol FindMethod(TypeSymbol receiver, string name, ImmutableArray <TypeSymbol> typeArgs, ImmutableArray <BoundExpression> args)
        {
            MethodSymbol            found      = null;
            bool                    ambiguous  = false;
            ImmutableArray <Symbol> candidates = receiver.GetMembers(name);

            foreach (var candidate in candidates)
            {
                var method = candidate as MethodSymbol;
                if ((object)method == null || method.Arity != typeArgs.Length || method.ParameterCount != args.Length)
                {
                    continue;
                }
                if (method.Arity != 0)
                {
                    method = method.Construct(typeArgs);
                }
                var  parameters = method.Parameters;
                bool exact      = true;

                for (int i = 0; i < args.Length; i++)
                {
                    HashSet <DiagnosticInfo> useSiteDiagnostics = null;
                    if (parameters[i].RefKind != RefKind.None ||
                        !((object)args[i].Type == null && parameters[i].Type.IsReferenceType ||
                          Compilation.Conversions.ClassifyConversion(args[i].Type, parameters[i].Type, ref useSiteDiagnostics).IsImplicit))
                    {
                        Debug.Assert(useSiteDiagnostics.IsNullOrEmpty());
                        goto nextCandidate;
                    }

                    Debug.Assert(useSiteDiagnostics.IsNullOrEmpty());
                    exact = exact && args[i].Type == parameters[i].Type;
                }

                if (exact)
                {
                    return(method);
                }
                if ((object)found != null)
                {
                    ambiguous = true;
                }
                found = method;

                nextCandidate :;
            }

            if (ambiguous)
            {
                ReportLibraryProblem(ErrorCode.ERR_LibraryMethodNotUnique, receiver, name, typeArgs, args);
            }
            else if ((object)found == null)
            {
                ReportLibraryProblem(ErrorCode.ERR_LibraryMethodNotFound, receiver, name, typeArgs, args);
            }
            return(found);
        }
 private static MethodSymbol GetRequiredMethod(TypeSymbol type, string methodName, DiagnosticBag diagnostics)
 {
     var method = type.GetMembers(methodName).SingleOrDefault() as MethodSymbol;
     if ((object)method == null)
     {
         diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, NoLocation.Singleton, type, methodName);
     }
     return method;
 }
Exemplo n.º 9
0
        /// <summary>
        /// Descends through Rest fields of a tuple if "symbol" is an extended field
        /// As a result the "symbol" will be adjusted to be the field of the innermost tuple
        /// and a corresponding containingSlot is returned.
        /// Return value -1 indicates a failure which could happen for the following reasons
        /// a) Rest field does not exist, which could happen in rare error scenarios involving broken ValueTuple types
        /// b) Rest is not tracked already and forceSlotsToExist is false (otherwise we create slots on demand)
        /// </summary>
        private int DescendThroughTupleRestFields(
            ref Symbol symbol,
            int containingSlot,
            bool forceContainingSlotsToExist
            )
        {
            if (symbol is TupleElementFieldSymbol fieldSymbol)
            {
                TypeSymbol containingType = symbol.ContainingType;

                // for tuple fields the variable identifier represents the underlying field
                symbol = fieldSymbol.TupleUnderlyingField;

                // descend through Rest fields
                // force corresponding slots if do not exist
                while (
                    !TypeSymbol.Equals(
                        containingType,
                        symbol.ContainingType,
                        TypeCompareKind.ConsiderEverything
                        )
                    )
                {
                    var restField =
                        containingType
                        .GetMembers(NamedTypeSymbol.ValueTupleRestFieldName)
                        .FirstOrDefault() as FieldSymbol;
                    if (restField is null)
                    {
                        return(-1);
                    }

                    if (forceContainingSlotsToExist)
                    {
                        containingSlot = GetOrCreateSlot(restField, containingSlot);
                    }
                    else
                    {
                        if (
                            !TryGetVariable(
                                new VariableIdentifier(restField, containingSlot),
                                out containingSlot
                                )
                            )
                        {
                            return(-1);
                        }
                    }

                    containingType = restField.Type;
                }
            }

            return(containingSlot);
        }
Exemplo n.º 10
0
        static bool IsAPairValue(TypeSymbol type, out Symbol key, out Symbol value)
        {
            key = value = default;

            if (type.IsValueType)
            {
                if (type.Name == "ValueTuple" && ((NamedTypeSymbol)type).Arity == 2)
                {
                    key   = type.GetMembers("Item1").Single();
                    value = type.GetMembers("Item2").Single();
                }
                else if (type.Name == "KeyValuePair" && ((NamedTypeSymbol)type).Arity == 2)
                {
                    key   = type.GetMembers("Key").Single();
                    value = type.GetMembers("Value").Single();
                }
            }

            //
            return(key != null && value != null);;
        }
Exemplo n.º 11
0
        private MethodSymbol getExplicitOperator(TypeSymbol srcType, TypeSymbol destType)
        {
            var members = srcType.GetMembers("op_Explicit");

            foreach (MethodSymbol m in members)
            {
                if (m.ReturnType == destType)
                {
                    return(m);
                }
            }
            return(null);
        }
Exemplo n.º 12
0
        public static bool HasMembers(this TypeSymbol type, string name)
        {
            TypeSymbol sym;

            sym = type;
            while (sym != null)
            {
                if (sym.GetMembers(name).Length > 0)
                {
                    return(true);
                }
                sym = sym.BaseTypeNoUseSiteDiagnostics;
            }
            return(false);
        }
Exemplo n.º 13
0
        public override (string file, string content)? GenerateOutput()
        {
            //If external
            if (this.HasCustomMap)
            {
                return(null);
            }
            var subClasses = new List <INamedTypeSymbol>();
            var sb         = new StringBuilder();

            var level = 0;

            //var hasModule = false;
            //if (!string.IsNullOrEmpty(Module) && Options.TypingsScope == TypingsScope.Global) {
            //	hasModule = true;
            //	sb.AppendLine($"declare module {Module} {{");
            //	level++;
            //}
            //var declaration = "declare ";
            //if (hasModule) { declaration = ""; }
            //if(Options.TypingsScope == TypingsScope.Module) {
            //	declaration = "export ";
            //}
            //sb.AppendLine(level, $"export const enum {TypeSymbol.Name} {{");
            sb.AppendLine(level, $"export enum {TypeSymbol.Name} {{");
            foreach (var m in TypeSymbol.GetMembers())
            {
                if (m.Kind == SymbolKind.Field)
                {
                    var f = m as IFieldSymbol;
                    sb.AppendLine(level + 1, $"{f.Name} = {f.ConstantValue},");
                }
            }
            sb.AppendLine(level, "}");
            //if (!string.IsNullOrEmpty(Module) && Options.TypingsScope == TypingsScope.Global) {
            //	sb.AppendLine("}");
            //}

            AppendKeysAndNames(sb);

            //File.WriteAllText(FileHelper.PathCombine(Options.ModelsDir, Filename), sb.ToString());
            //string file = FileHelper.PathCombine(Options.TypingsDir, Filename);
            string content = sb.ToString();

            return(OutputFilePath, content);
            //await FileHelper.WriteAsync(file, content);
            //return file;
        }
Exemplo n.º 14
0
        /// <summary>
        /// Builds a layout for a given type.
        /// First traverses all base types and builds their layouts when needed since the base type layouts inform the layout of derived types.
        /// </summary>
        private void BuildLayout(TypeSymbol typeSymbol, AbstractPhaseContext context)
        {
            Stack <TypeSymbol> typesToBuild = new Stack <TypeSymbol>();

            while (typeSymbol.BaseType != null && !_builtLayouts.ContainsKey(typeSymbol))
            {
                typesToBuild.Push(typeSymbol);
                if (typeSymbol == _udonSharpBehaviourType)
                {
                    break;
                }

                typeSymbol = typeSymbol.BaseType;
            }

            while (typesToBuild.Count > 0)
            {
                TypeSymbol currentBuildType = typesToBuild.Pop();

                Dictionary <string, int> idCounters;

                if (currentBuildType.BaseType != null &&
                    _builtLayouts.TryGetValue(currentBuildType.BaseType, out TypeLayout parentLayout))
                {
                    idCounters = new Dictionary <string, int>(parentLayout.SymbolCounters);
                }
                else
                {
                    idCounters = new Dictionary <string, int>();
                }

                Dictionary <MethodSymbol, MethodExportLayout> layouts =
                    new Dictionary <MethodSymbol, MethodExportLayout>();

                foreach (Symbol symbol in currentBuildType.GetMembers(context))
                {
                    if (symbol is MethodSymbol methodSymbol &&
                        (methodSymbol.OverridenMethod == null ||
                         methodSymbol.OverridenMethod.ContainingType == _udonSharpBehaviourType ||
                         methodSymbol.OverridenMethod.ContainingType.IsExtern))
                    {
                        layouts.Add(methodSymbol, BuildMethodLayout(methodSymbol, idCounters));
                    }
                }

                _builtLayouts.Add(currentBuildType, new TypeLayout(layouts, idCounters));
            }
        }
Exemplo n.º 15
0
        private MetadataReference GenerateShallowReference()
        {
            ShallowCompilation = CSharpCompilation.Create(
                assemblyName: AssemblyName,
                options: Worker.OriginalCompilation.Options,
                references: Worker.OriginalCompilation.References);

            foreach (var other in Requires)
            {
                if (other.Value == AssemblyNeutralWorker.OrderingState.StrengthKind.DeepUsage)
                {
                    ShallowCompilation = ShallowCompilation.AddReferences(other.Key.RealOrShallowReference());
                }
            }

            foreach (var syntaxReference in TypeSymbol.DeclaringSyntaxReferences)
            {
                var node = syntaxReference.GetSyntax();
                var tree = syntaxReference.SyntaxTree;
                var root = tree.GetRoot();

                var nodesToRemove = GetNodesToRemove(root, node);

                foreach (var member in TypeSymbol.GetMembers())
                {
                    foreach (var memberSyntaxReference in member.DeclaringSyntaxReferences)
                    {
                        if (memberSyntaxReference.SyntaxTree == tree)
                        {
                            nodesToRemove = nodesToRemove.Concat(new[] { memberSyntaxReference.GetSyntax() });
                        }
                    }
                }

                var newRoot = root.RemoveNodes(nodesToRemove.ToArray(), SyntaxRemoveOptions.KeepDirectives);
                var newTree = SyntaxFactory.SyntaxTree(newRoot, options: tree.Options, path: tree.FilePath, encoding: Encoding.UTF8);

                ShallowCompilation = ShallowCompilation.AddSyntaxTrees(newTree);
            }
            ShallowOutputStream          = new MemoryStream();
            ShallowEmitResult            = ShallowCompilation.Emit(ShallowOutputStream);
            ShallowOutputStream.Position = 0;
            ShallowReference             = new MetadataImageReference(ShallowOutputStream);
            ShallowOutputStream.Position = 0;
            return(ShallowReference);
        }
Exemplo n.º 16
0
        private static FieldSymbol FindFieldBySignature(TypeSymbol targetTypeSymbol, string targetMemberName, ImmutableArray <ModifierInfo> customModifiers, TypeSymbol type)
        {
            foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName))
            {
                var field = member as FieldSymbol;
                if ((object)field != null &&
                    field.Type == type &&
                    CustomModifiersMatch(field.CustomModifiers, customModifiers))
                {
                    // Behavior in the face of multiple matching signatures is
                    // implementation defined - we'll just pick the first one.
                    return(field);
                }
            }

            return(null);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Gets the most derived method of a given method symbol in the current emit type's context.
        /// </summary>
        /// <param name="methodSymbol"></param>
        /// <returns></returns>
        private MethodSymbol GetMostDerivedMethod(MethodSymbol methodSymbol)
        {
            if (!methodSymbol.HasOverrides)
            {
                return(methodSymbol);
            }

            TypeSymbol currentSearchType = EmitType;

            MethodSymbol derivedSymbol = null;

            while (currentSearchType != null)
            {
                foreach (var symbol in currentSearchType.GetMembers <MethodSymbol>(methodSymbol.Name, this))
                {
                    if (symbol.Parameters.Length != methodSymbol.Parameters.Length) // early out when the method obviously doesn't overload this
                    {
                        continue;
                    }

                    MethodSymbol currentMethod = symbol;

                    while (currentMethod != null && currentMethod != methodSymbol)
                    {
                        currentMethod = currentMethod.OverridenMethod;
                    }

                    if (currentMethod == methodSymbol)
                    {
                        derivedSymbol = symbol;
                        break;
                    }
                }

                if (derivedSymbol != null)
                {
                    break;
                }

                currentSearchType = currentSearchType.BaseType;
            }

            return(derivedSymbol);
        }
Exemplo n.º 18
0
        private static bool TryCreateInstantiationInvocation(AbstractPhaseContext context, SyntaxNode node,
                                                             MethodSymbol symbol, BoundExpression instanceExpression, BoundExpression[] parameterExpressions,
                                                             out BoundInvocationExpression createdInvocation)
        {
            switch (symbol.Name)
            {
            case "Instantiate_Extern" when symbol.ContainingType == context.GetTypeSymbol(typeof(InstantiationShim)):
                createdInvocation = new BoundExternInvocation(node, context,
                                                              new ExternSynthesizedMethodSymbol(context,
                                                                                                "VRCInstantiate.__Instantiate__UnityEngineGameObject__UnityEngineGameObject",
                                                                                                parameterExpressions.Select(e => e.ValueType).ToArray(),
                                                                                                context.GetTypeSymbol(typeof(GameObject)), true),
                                                              instanceExpression, parameterExpressions);

                return(true);

            case "VRCInstantiate" when symbol.ContainingType == context.GetTypeSymbol(typeof(UdonSharpBehaviour)):     // Backwards compatibility for UdonSharpBehaviour.VRCInstantiate
            case "Instantiate" when symbol.ContainingType == context.GetTypeSymbol(typeof(UnityEngine.Object)):
            {
                if (symbol.Name != "VRCInstantiate" &&
                    (symbol.TypeArguments.Length != 1 ||
                     symbol.TypeArguments[0] != context.GetTypeSymbol(typeof(GameObject))))
                {
                    throw new NotSupportedException("Udon does not support instantiating non-GameObject types");
                }

                TypeSymbol   instantiateShim   = context.GetTypeSymbol(typeof(InstantiationShim));
                MethodSymbol instantiateMethod = instantiateShim.GetMembers <MethodSymbol>("Instantiate", context)
                                                 .First(e => e.Parameters
                                                        .Select(p => p.Type)
                                                        .SequenceEqual(parameterExpressions
                                                                       .Select(p => p.ValueType)));

                context.MarkSymbolReferenced(instantiateMethod);

                createdInvocation = new BoundStaticUserMethodInvocation(node, instantiateMethod, parameterExpressions);
                return(true);
            }
            }

            createdInvocation = null;
            return(false);
        }
Exemplo n.º 19
0
        public void SymbolUsage(Action <ISymbol> shallowUsage, Action <ISymbol> deepUsage)
        {
            DoTypeSymbol(deepUsage, TypeSymbol.BaseType);

            foreach (var symbol in TypeSymbol.AllInterfaces)
            {
                DoTypeSymbol(deepUsage, symbol);
            }

            AttributeDataSymbolUsage(TypeSymbol.GetAttributes(), deepUsage);

            foreach (var member in TypeSymbol.GetMembers())
            {
                AttributeDataSymbolUsage(member.GetAttributes(), deepUsage);

                var propertyMember = member as IPropertySymbol;
                var fieldMember    = member as IFieldSymbol;
                var methodMember   = member as IMethodSymbol;

                if (propertyMember != null)
                {
                    DoTypeSymbol(shallowUsage, propertyMember.Type);
                }

                if (fieldMember != null)
                {
                    DoTypeSymbol(shallowUsage, fieldMember.Type);
                }

                if (methodMember != null)
                {
                    DoTypeSymbol(shallowUsage, methodMember.ReturnType);
                    AttributeDataSymbolUsage(methodMember.GetReturnTypeAttributes(), deepUsage);
                    foreach (var parameter in methodMember.Parameters)
                    {
                        DoTypeSymbol(shallowUsage, parameter.Type);
                        AttributeDataSymbolUsage(parameter.GetAttributes(), deepUsage);
                    }
                }
            }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Descends through Rest fields of a tuple if "symbol" is an extended field
        /// As a result the "symbol" will be adjusted to be the field of the innermost tuple
        /// and a corresponding containingSlot is returned.
        /// Return value -1 indicates a failure which could happen for the following reasons
        /// a) Rest field does not exist, which could happen in rare error scenarios involving broken ValueTuple types
        /// b) Rest is not tracked already and forceSlotsToExist is false (otherwise we create slots on demand)
        /// </summary>
        private int DescendThroughTupleRestFields(ref Symbol symbol, int containingSlot, bool forceContainingSlotsToExist)
        {
            var fieldSymbol = symbol as TupleFieldSymbol;

            if ((object)fieldSymbol != null)
            {
                TypeSymbol containingType = ((TupleTypeSymbol)symbol.ContainingType).UnderlyingNamedType;

                // for tuple fields the variable identifier represents the underlying field
                symbol = fieldSymbol.TupleUnderlyingField;

                // descend through Rest fields
                // force corresponding slots if do not exist
                while (containingType != symbol.ContainingType)
                {
                    var restField = containingType.GetMembers(TupleTypeSymbol.RestFieldName).FirstOrDefault() as FieldSymbol;
                    if ((object)restField == null)
                    {
                        return(-1);
                    }

                    if (forceContainingSlotsToExist)
                    {
                        containingSlot = GetOrCreateSlot(restField, containingSlot);
                    }
                    else
                    {
                        if (!_variableSlot.TryGetValue(new VariableIdentifier(restField, containingSlot), out containingSlot))
                        {
                            return(-1);
                        }
                    }

                    containingType = restField.Type.TypeSymbol.TupleUnderlyingTypeOrSelf();
                }
            }

            return(containingSlot);
        }
        /// <summary>
        /// Might the given type be, or contain, managed references?  This is used to determine which
        /// fields allocated to temporaries should be cleared when the underlying variable goes out of scope, so
        /// that they do not cause unnecessary object retention.
        /// </summary>
        private bool MightContainReferences(TypeSymbol type)
        {
            if (type.IsReferenceType || type.TypeKind == TypeKind.TypeParameter)
            {
                return(true);                                                                 // type parameter or reference type
            }
            if (type.TypeKind != TypeKind.Struct)
            {
                return(false);                                  // enums, etc
            }
            if (type.SpecialType == SpecialType.System_TypedReference)
            {
                return(true);
            }
            if (type.SpecialType != SpecialType.None)
            {
                return(false);                                      // int, etc
            }
            CSharpCompilation Compilation = this.CompilationState.ModuleBuilderOpt.Compilation;

            if (type.DeclaringCompilation != Compilation)
            {
                return(true);                                          // perhaps from ref assembly
            }
            if (emptyStructTypeCache.IsEmptyStructType(type))
            {
                return(false);
            }
            foreach (var f in type.GetMembers())
            {
                if (f.Kind == SymbolKind.Field && !f.IsStatic && MightContainReferences(((FieldSymbol)f).Type))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemplo n.º 22
0
        private static bool ClearGlobals(CSharpCompilation compilation, SyntaxNode node, TypeSymbol functionClass, List <BoundStatement> statements)
        {
            var  members = functionClass.GetMembers();
            bool added   = false;

            foreach (var member in members)
            {
                if (member.IsStatic && member.Kind == SymbolKind.Field)
                {
                    var field   = member as FieldSymbol;
                    var fldtype = field.Type;
                    if (field.DeclaredAccessibility == Accessibility.Public &&
                        fldtype.TypeKind == TypeKind.Class &&
                        !field.IsReadOnly &&
                        !field.IsConst
                        )
                    {
                        statements.Add(ClearGlobal(compilation, node, field));
                        added = true;
                    }
                }
            }
            return(added);
        }
Exemplo n.º 23
0
        // Does a member lookup in a single type, without considering inheritance.
        private LookupResult MemberLookupWithoutInheritance(TypeSymbol type, string name, int arity, bool invoked)
        {
            LookupResult result = new LookupResult();

            IEnumerable <Symbol> members = type.GetMembers(name);

            foreach (Symbol member in members)
            {
                LookupResult resultOfThisMember;
                // Do we need to exclude override members, or is that done later by overload resolution. It seems like
                // not excluding them here can't lead to problems, because we will always find the overridden method as well.

                SymbolKind     memberKind = member.Kind;
                DiagnosticInfo diagInfo;
                if (WrongArity(member, arity, out diagInfo))
                {
                    resultOfThisMember = LookupResult.WrongArity(member, diagInfo);
                }
                else if (invoked && !IsInvocable(member))
                {
                    resultOfThisMember = LookupResult.Bad(member, new CSDiagnosticInfo(ErrorCode.ERR_NonInvocableMemberCalled, member.GetFullName()));
                }
                else if (!IsMemberAccessible(member))
                {
                    resultOfThisMember = LookupResult.Inaccessible(member);
                }
                else
                {
                    resultOfThisMember = LookupResult.Good(member);
                }

                result = MergeLookupsInSameScope(result, resultOfThisMember);
            }

            return(result);
        }
Exemplo n.º 24
0
        public OutputFileAbstraction GetAbstraction()
        {
            var context            = new ResolutionContext(this);
            var serviceAbstraction = new ServiceAbstraction();

            serviceAbstraction.Path           = AbstractPath;
            serviceAbstraction.ClassName      = ClassName;
            serviceAbstraction.ControllerName = TypeSymbol.Name;
            serviceAbstraction.Actions        = new List <ActionAbstraction>();

            //Resolve endpoint
            var routeAttr = TypeSymbol.GetAttributes().FirstOrDefault(a => a.AttributeClass.Name == "Route" || a.AttributeClass.Name.ToString() == "RoutePrefix");
            var arg       = (routeAttr.ApplicationSyntaxReference.GetSyntax() as AttributeSyntax).ArgumentList.Arguments[0].ToString().Replace("\"", "");
            var path      = arg.Replace("[controller]", ControllerName.ToCamelCase());

            serviceAbstraction.Endpoint = path;

            //Actions
            var existingMethods = new Dictionary <string, int>();

            foreach (var m in TypeSymbol.GetMembers())
            {
                if (m.Kind == SymbolKind.NamedType)
                {
                    continue;
                }
                if (m.DeclaredAccessibility != Accessibility.Public)
                {
                    continue;
                }
                if (m.IsStatic)
                {
                    continue;
                }
                if (m.Kind != SymbolKind.Method)
                {
                    continue;
                }
                if (m.IsImplicitlyDeclared)
                {
                    continue;
                }
                if (!m.IsDefinition)
                {
                    continue;
                }
                var mtd = m as IMethodSymbol;
                if (m.Name == ".ctor")
                {
                    continue;
                }


                var actionAbstraction = new ActionAbstraction();
                serviceAbstraction.Actions.Add(actionAbstraction);


                var mtdAttrs       = mtd.GetAttributes();
                var returnType     = TypeResolver.Resolve(mtd.ReturnType as ITypeSymbol, context);
                var returnTypeName = returnType.Declaration;
                //Not marked actions will accept posts
                var    httpMethod = "Post";
                string action     = "";

                //Get http method from method name pattern
                if (mtd.Name.StartsWith("Get"))
                {
                    httpMethod = "Get";
                }
                if (mtd.Name.StartsWith("Post"))
                {
                    httpMethod = "Post";
                }
                if (mtd.Name.StartsWith("Put"))
                {
                    httpMethod = "Put";
                }
                if (mtd.Name.StartsWith("Delete"))
                {
                    httpMethod = "Delete";
                }
                if (mtd.Name.StartsWith("Patch"))
                {
                    httpMethod = "Patch";
                }
                var methodName = mtd.Name.ToCamelCase();
                if (existingMethods.ContainsKey(methodName))
                {
                    existingMethods[methodName]++;
                    methodName = $"{methodName}_{existingMethods[methodName]}";
                }
                else
                {
                    existingMethods.Add(methodName, 0);
                }

                actionAbstraction.FunctionName = methodName;

                var httpAttr        = mtdAttrs.FirstOrDefault(a => a.AttributeClass.Name.StartsWith("Http"));
                var routeMethodAttr = mtdAttrs.FirstOrDefault(a => a.AttributeClass.Name.StartsWith("Route"));
                //If has Http attribute
                if (httpAttr != null)
                {
                    httpMethod = httpAttr.AttributeClass.Name.Substring(4);
                    //Check if it contains route info
                    var args = (httpAttr.ApplicationSyntaxReference.GetSyntax() as AttributeSyntax)?.ArgumentList?.Arguments;
                    if (args != null && args.Value.Count > 0)
                    {
                        action = args.Value[0].ToString().Replace("\"", "");
                    }
                }
                //Check if contains route attr
                if (routeMethodAttr != null)
                {
                    var args = (routeMethodAttr.ApplicationSyntaxReference.GetSyntax() as AttributeSyntax).ArgumentList.Arguments;
                    if (args.Count > 0)
                    {
                        action = args[0].ToString().Replace("\"", "");
                    }
                }
                //Replace route variables
                action = action.Replace("[action]", methodName);

                var regex = new Regex(@"\{(?<paramName>\w+)(:\w+(\(.*?\))?)?\??}");
                action = regex.Replace(action, match =>
                {
                    return($"${{{match.Groups["paramName"].Value}}}");
                });

                //Resolve how parameters are sent
                var pendingParameters    = new List <ParameterResolution>();
                var parameterResolutions = mtd.Parameters.Select(p => new ParameterResolution(p, TypeResolver, context, Options)).Where(p => !p.Ignore);
                foreach (var pr in parameterResolutions)
                {
                    //[FromRoute]
                    if (action.Contains($"{{{pr.Name}}}"))
                    {
                        //Casting to any because encodeURIComponent expects string
                        action = action.Replace($"{{{pr.Name}}}", $"{{encodeURIComponent(<any>{pr.Name})}}");
                        continue;
                    }

                    //[FromBody]
                    if (pr.From == ParameterFromKind.FromBody)
                    {
                        actionAbstraction.BodyParameterName = pr.Name;
                        continue;
                    }
                    pendingParameters.Add(pr);
                }
                var strParameters = string.Join(", ", parameterResolutions.Select(pr => pr.Signature));

                actionAbstraction.Parameters = parameterResolutions.Select(p => new ParameterAbstraction {
                    Name       = p.Name,
                    IsOptional = p.IsOptional,
                    //TypeDescription = p.TypeDescription
                    Type = p.Type
                }).ToList();

                actionAbstraction.ReturnType = returnType;
                //action
                actionAbstraction.ActionName = action;
                //httpMethod
                actionAbstraction.HttpMethod = httpMethod;

                actionAbstraction.SearchParametersNames = new List <string>();

                //Body
                switch (httpMethod)
                {
                case "Put":
                case "Patch":
                case "Post":
                    break;

                default:
                    actionAbstraction.BodyParameterName = null;
                    break;
                }

                //Search
                actionAbstraction.SearchParametersNames = pendingParameters.Select(pr => pr.Name).ToList();
            }

            serviceAbstraction.Imports = context.GetImports();
            return(serviceAbstraction);
        }
 /// <summary>
 /// Might the given type be, or contain, managed references?  This is used to determine which
 /// fields allocated to temporaries should be cleared when the underlying variable goes out of scope, so
 /// that they do not cause unnecessary object retention.
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 private bool MightContainReferences(TypeSymbol type)
 {
     if (type.IsReferenceType || type.TypeKind == TypeKind.TypeParameter) return true; // type parameter or reference type
     if (type.TypeKind != TypeKind.Struct) return false; // enums, etc
     if (type.SpecialType == SpecialType.System_TypedReference) return true;
     if (type.SpecialType != SpecialType.None) return false; // int, etc
     CSharpCompilation Compilation = this.CompilationState.ModuleBuilderOpt.Compilation;
     if (type.DeclaringCompilation != Compilation) return true; // perhaps from ref assembly
     if (emptyStructTypeCache.IsEmptyStructType(type)) return false;
     foreach (var f in type.GetMembers())
     {
         if (f.Kind == SymbolKind.Field && !f.IsStatic && MightContainReferences(((FieldSymbol)f).Type)) return true;
     }
     return false;
 }
Exemplo n.º 26
0
        public static BoundStatement RewriteAppExit(
            MethodSymbol method,
            BoundStatement statement,
            DiagnosticBag diagnostics)

        {
            if (method.Name != XSharpSpecialNames.AppExit)
            {
                return(statement);
            }
            var refMan        = method.DeclaringCompilation.GetBoundReferenceManager();
            var vcla          = method.DeclaringCompilation.ClassLibraryType();
            var newstatements = new List <BoundStatement>();

            foreach (var rkv in refMan.GetReferencedAssemblies())
            {
                var r = rkv.Value;
                foreach (var attr in r.GetAttributes())
                {
                    if ((Symbol)attr.AttributeClass.ConstructedFrom == vcla)
                    {
                        var attargs = attr.CommonConstructorArguments;
                        if (attargs.Length == 2)
                        {
                            var functionsClassName = attargs[0].Value.ToString();
                            if (!string.IsNullOrEmpty(functionsClassName))
                            {
                                TypeSymbol type = r.GetTypeByMetadataName(functionsClassName) as TypeSymbol;
                                // If we can find the $Exit method then call that method
                                // Otherwise find the public globals and clear them from our code
                                if (type != null)
                                {
                                    var members = type.GetMembers(XSharpSpecialNames.ExitProc);
                                    if (members.Length > 0)
                                    {
                                        foreach (MethodSymbol sym in members)
                                        {
                                            CreateMethodCall(method.DeclaringCompilation, statement.Syntax, sym, newstatements);
                                        }
                                    }
                                    else
                                    {
                                        ClearGlobals(method.DeclaringCompilation, statement.Syntax, type, newstatements);
                                    }
                                }
                            }
                        }
                        break;
                    }
                }
            }
            // Now clear the globals in this assembly by calling $Exit

            var symbols = FindMembers(method.DeclaringCompilation, XSharpSpecialNames.ExitProc);

            foreach (MethodSymbol sym in symbols)
            {
                CreateMethodCall(method.DeclaringCompilation, statement.Syntax, sym, newstatements);
            }
            newstatements.Add(new BoundReturnStatement(statement.Syntax, RefKind.None, null));
            var oldbody = statement as BoundBlock;
            var newbody = oldbody.Update(oldbody.Locals, ImmutableArray <LocalFunctionSymbol> .Empty, newstatements.ToImmutableArray <BoundStatement>());

            return(newbody);
        }
Exemplo n.º 27
0
        private MethodSymbol FindMethod(TypeSymbol receiver, string name, ImmutableArray<TypeSymbol> typeArgs, ImmutableArray<BoundExpression> args)
        {
            MethodSymbol found = null;
            bool ambiguous = false;
            ImmutableArray<Symbol> candidates = receiver.GetMembers(name);
            foreach (var candidate in candidates)
            {
                var method = candidate as MethodSymbol;
                if ((object)method == null || method.Arity != typeArgs.Length || method.ParameterCount != args.Length) continue;
                if (method.Arity != 0) method = method.Construct(typeArgs);
                var parameters = method.Parameters;
                bool exact = true;

                for (int i = 0; i < args.Length; i++)
                {
                    HashSet<DiagnosticInfo> useSiteDiagnostics = null;
                    if (parameters[i].RefKind != RefKind.None ||
                        !((object)args[i].Type == null && parameters[i].Type.IsReferenceType ||
                        Compilation.Conversions.ClassifyConversion(args[i].Type, parameters[i].Type, ref useSiteDiagnostics).IsImplicit))
                    {
                        Debug.Assert(useSiteDiagnostics.IsNullOrEmpty());
                        goto nextCandidate;
                    }

                    Debug.Assert(useSiteDiagnostics.IsNullOrEmpty());
                    exact = exact && args[i].Type == parameters[i].Type;
                }

                if (exact) return method;
                if ((object)found != null)
                {
                    ambiguous = true;
                }
                found = method;

                nextCandidate: ;
            }

            if (ambiguous) ReportLibraryProblem(ErrorCode.ERR_LibraryMethodNotUnique, receiver, name, typeArgs, args);
            else if ((object)found == null) ReportLibraryProblem(ErrorCode.ERR_LibraryMethodNotFound, receiver, name, typeArgs, args);
            return found;
        }
Exemplo n.º 28
0
        private static FieldSymbol FindFieldBySignature(TypeSymbol targetTypeSymbol, string targetMemberName, ImmutableArray<ModifierInfo<TypeSymbol>> customModifiers, TypeSymbol type)
        {
            foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName))
            {
                var field = member as FieldSymbol;
                if ((object)field != null &&
                    field.Type == type &&
                    CustomModifiersMatch(field.CustomModifiers, customModifiers))
                {
                    // Behavior in the face of multiple matching signatures is
                    // implementation defined - we'll just pick the first one.
                    return field;
                }
            }

            return null;
        }
        private MethodSymbol DelegateConstructor(CSharpSyntaxNode syntax, TypeSymbol delegateType)
        {
            foreach (var possibleCtor in delegateType.GetMembers(WellKnownMemberNames.InstanceConstructorName))
            {
                var m = possibleCtor as MethodSymbol;
                if ((object)m == null) continue;
                var parameters = m.Parameters;
                if (parameters.Length != 2) continue;
                if (parameters[0].Type.SpecialType != SpecialType.System_Object) continue;
                var p1t = parameters[1].Type.SpecialType;
                if (p1t == SpecialType.System_IntPtr || p1t == SpecialType.System_UIntPtr)
                {
                    return m;
                }
            }

            // The delegate '{0}' does not have a valid constructor
            diagnostics.Add(ErrorCode.ERR_BadDelegateConstructor, syntax.Location, delegateType);
            return null;
        }
Exemplo n.º 30
0
 private static MethodSymbol GetRequiredMethod(TypeSymbol type, string methodName, DiagnosticBag diagnostics)
 {
     var method = type.GetMembers(methodName).SingleOrDefault() as MethodSymbol;
     if ((object)method == null)
     {
         diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, NoLocation.Singleton, type, methodName);
     }
     return method;
 }
Exemplo n.º 31
0
 public override IEnumerable <Symbol> GetMembers()
 {
     return(referencedType.GetMembers());
 }
        // Does a member lookup in a single type, without considering inheritance.
        private LookupResult MemberLookupWithoutInheritance(TypeSymbol type, string name, int arity, bool invoked)
        {
            LookupResult result = new LookupResult();

            IEnumerable<Symbol> members = type.GetMembers(name);
            foreach (Symbol member in members) {
                LookupResult resultOfThisMember;
                // Do we need to exclude override members, or is that done later by overload resolution. It seems like
                // not excluding them here can't lead to problems, because we will always find the overridden method as well.

                SymbolKind memberKind = member.Kind;
                DiagnosticInfo diagInfo;
                if (WrongArity(member, arity, out diagInfo))
                    resultOfThisMember = LookupResult.WrongArity(member, diagInfo);
                else if (invoked && !IsInvocable(member))
                    resultOfThisMember = LookupResult.Bad(member, new CSDiagnosticInfo(ErrorCode.ERR_NonInvocableMemberCalled, member.GetFullName()));
                else if (!IsMemberAccessible(member))
                    resultOfThisMember = LookupResult.Inaccessible(member);
                else
                    resultOfThisMember = LookupResult.Good(member);

                result = MergeLookupsInSameScope(result, resultOfThisMember);
            }

            return result;
        }
Exemplo n.º 33
0
        public void Emit()
        {
            _returnValue = RootTable.CreateInternalValue(GetTypeSymbol(SpecialType.System_UInt32), "returnJump");

            CurrentNode = EmitType.RoslynSymbol.DeclaringSyntaxReferences.First().GetSyntax();

            DefaultExecutionOrder executionOrder = EmitType.GetAttribute <DefaultExecutionOrder>();

            if (executionOrder != null)
            {
                if (executionOrder.order < (int.MinValue + 1000000))
                {
                    throw new CompilerException($"Execution orders below int.MinValue + 1000000 are reserved for internal use in U#");
                }

                Module.ExecutionOrder = executionOrder.order;
            }

            TypeSymbol udonSharpBehaviourType = GetTypeSymbol(typeof(UdonSharpBehaviour));

            Stack <TypeSymbol> emitTypeBases = new Stack <TypeSymbol>();

            TypeSymbol currentEmitType = EmitType;

            while (currentEmitType.BaseType != null)
            {
                emitTypeBases.Push(currentEmitType);
                currentEmitType = currentEmitType.BaseType;

                if (currentEmitType == udonSharpBehaviourType)
                {
                    break;
                }
            }

            if (currentEmitType != udonSharpBehaviourType)
            {
                throw new NotSupportedException("U# behaviour must inherit from UdonSharpBehaviour",
                                                currentEmitType.RoslynSymbol.DeclaringSyntaxReferences.First().GetSyntax().GetLocation());
            }

            List <MethodSymbol> rootMethods = new List <MethodSymbol>();

            List <FieldSymbol>    userFields    = new List <FieldSymbol>();
            HashSet <FieldSymbol> visitedFields = new HashSet <FieldSymbol>();

            // Visits each base class and searches for the most derived version of a method if it is overriden
            // The intention with this is to ensure a consistent ordering between all inheritors of a base class
            // This means that we can know that all inheritors of a class have the same method names and parameter symbol allocations
            //   which allows people to call virtual methods on UdonSharpBehaviours and have Udon just make it work
            while (emitTypeBases.Count > 0)
            {
                TypeSymbol currentBase = emitTypeBases.Pop();

                // Make sure fields get emitted
                foreach (FieldSymbol field in currentBase.GetMembers <FieldSymbol>(this))
                {
                    if (field.IsConst)
                    {
                        continue;
                    }

                    if (!visitedFields.Contains(field))
                    {
                        userFields.Add(field);
                        visitedFields.Add(field);
                    }

                    GetUserValue(field);
                }

                foreach (MethodSymbol methodSymbol in currentBase.GetMembers <MethodSymbol>(this))
                {
                    if (methodSymbol.RoslynSymbol.IsImplicitlyDeclared ||
                        methodSymbol.RoslynSymbol.IsStatic)
                    {
                        continue;
                    }

                    if (methodSymbol.HasOverrides)
                    {
                        MethodSymbol derivedMethod = GetMostDerivedMethod(methodSymbol);

                        if (derivedMethod.RoslynSymbol.IsAbstract)
                        {
                            continue;
                        }

                        if (!rootMethods.Contains(derivedMethod))
                        {
                            rootMethods.Add(derivedMethod);
                        }
                    }
                    else if (!rootMethods.Contains(methodSymbol))
                    {
                        if (methodSymbol.RoslynSymbol.IsAbstract)
                        {
                            continue;
                        }

                        rootMethods.Add(methodSymbol);
                    }
                }
            }

            DeclaredFields = userFields.ToImmutableArray();
            InitConstFields();

            HashSet <MethodSymbol> emittedSet = new HashSet <MethodSymbol>();
            HashSet <MethodSymbol> setToEmit  = new HashSet <MethodSymbol>();

            // Do not roll this into the while loop, the order must be maintained for the root symbols so calls across behaviours work consistently
            foreach (MethodSymbol methodSymbol in rootMethods)
            {
                using (new MethodEmitScope(methodSymbol, this))
                {
                    methodSymbol.Emit(this);
                }

                emittedSet.Add(methodSymbol);

                setToEmit.UnionWith(methodSymbol.DirectDependencies.OfType <MethodSymbol>());
            }

            while (setToEmit.Count > 0)
            {
                HashSet <MethodSymbol> newEmitSet = new HashSet <MethodSymbol>();

                foreach (var methodSymbol in setToEmit)
                {
                    if (emittedSet.Contains(methodSymbol))
                    {
                        continue;
                    }
                    if (methodSymbol.RoslynSymbol != null)
                    {
                        if (methodSymbol.RoslynSymbol.IsAbstract || methodSymbol.IsUntypedGenericMethod)
                        {
                            continue;
                        }
                    }

                    if (!methodSymbol.IsStatic && methodSymbol.ContainingType.IsUdonSharpBehaviour) // Prevent other behaviour type's methods from leaking into this type from calls across behaviours
                    {
                        TypeSymbol topType   = EmitType;
                        bool       foundType = false;
                        while (topType != udonSharpBehaviourType)
                        {
                            if (methodSymbol.ContainingType == topType)
                            {
                                foundType = true;
                                break;
                            }
                            topType = topType.BaseType;
                        }

                        if (!foundType)
                        {
                            continue;
                        }
                    }

                    using (new MethodEmitScope(methodSymbol, this))
                    {
                        methodSymbol.Emit(this);
                    }

                    emittedSet.Add(methodSymbol);

                    newEmitSet.UnionWith(methodSymbol.DirectDependencies.OfType <MethodSymbol>());
                }

                setToEmit = newEmitSet;
            }

            if (_recursiveStackVal != null)
            {
                _recursiveStackVal.DefaultValue = new object[_maxRecursiveStackPush];
            }

            DebugInfo.FinalizeAssemblyInfo();
        }
Exemplo n.º 34
0
        private static MethodSymbol FindMethodBySignature(TypeSymbol targetTypeSymbol, string targetMemberName, SignatureHeader targetMemberSignatureHeader, int targetMemberTypeParamCount, ParamInfo<TypeSymbol>[] targetParamInfo)
        {
            foreach (Symbol member in targetTypeSymbol.GetMembers(targetMemberName))
            {
                var method = member as MethodSymbol;
                if ((object)method != null &&
                    ((byte)method.CallingConvention == targetMemberSignatureHeader.RawValue) &&
                    (targetMemberTypeParamCount == method.Arity) &&
                    MethodSymbolMatchesParamInfo(method, targetParamInfo))
                {
                    // Behavior in the face of multiple matching signatures is
                    // implementation defined - we'll just pick the first one.
                    return method;
                }
            }

            return null;
        }
Exemplo n.º 35
0
        IEnumerable <Cci.MethodImplementation> Cci.ITypeDefinition.GetExplicitImplementationOverrides(EmitContext context)
        {
            CheckDefinitionInvariant();

            if (this.IsInterface)
            {
                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());
                    }
                }
            }
        }
Exemplo n.º 36
0
        private (string file, string content) GenerateOutputModule()
        {
            //var hasConsts = false;
            //var subClasses = new List<INamedTypeSymbol>();
            var sb      = new StringBuilder();
            var context = new ResolutionContext(this);
            var level   = 0;

            if (!TypeSymbol.IsStatic)
            {
                string inheritance = "";

                if (TypeSymbol.BaseType != null && TypeSymbol.BaseType.SpecialType != SpecialType.System_Object)
                {
                    var inheritanceTypeResolution = TypeResolver.Resolve(TypeSymbol.BaseType, context);
                    if (inheritanceTypeResolution.IsAny)
                    {
                        if (inheritanceTypeResolution.Declaration.Contains("/*"))
                        {
                            inheritance = $"/*extends {inheritanceTypeResolution.Declaration.Replace("any/*", "").Replace("*/", "")}*/";
                        }
                    }
                    else
                    {
                        inheritance = $"extends {inheritanceTypeResolution.Declaration} ";
                    }
                }

                string genericArguments = "";
                if (TypeSymbol.TypeArguments.Any())
                {
                    genericArguments = $"<{string.Join(", ", TypeSymbol.TypeArguments.Select(t => t.Name))}>";
                }

                sb.AppendLine(level, $"export interface {ClassName}{genericArguments} {inheritance}{{");
                foreach (var m in TypeSymbol.GetMembers())
                {
                    if (m.Kind == SymbolKind.NamedType)
                    {
                        //subClasses.Add(m as INamedTypeSymbol);
                        continue;
                    }
                    if (m.IsStatic)
                    {
                        //if (m.Kind == SymbolKind.Field && (m as IFieldSymbol).IsConst)
                        //{
                        //    hasConsts = true;
                        //}
                        continue;
                    }
                    if (m.Kind != SymbolKind.Property)
                    {
                        continue;
                    }
                    if (m.DeclaredAccessibility != Accessibility.Public)
                    {
                        continue;
                    }
                    var prop       = m as IPropertySymbol;
                    var isNullable = TypeResolver.IsNullable(prop.Type) || !prop.Type.IsValueType;
                    var name       = Options.KeepPropsCase ? m.Name : m.Name.ToCamelCase();

                    var summary = prop.GetDocumentationCommentXml();
                    if (!string.IsNullOrWhiteSpace(summary))
                    {
                        summary = summary.Split("<summary>").Last().Split("</summary>").First().Trim();
                        sb.AppendLine(level + 1, "/**");
                        var lines = summary.Split(System.Environment.NewLine);
                        foreach (var l in lines)
                        {
                            sb.AppendLine(level + 1, $"*{l.Trim()}");
                        }
                        sb.AppendLine(level + 1, "**/");
                    }

                    sb.AppendLine(level + 1, $"{name}{(isNullable ? "?" : "")}: {TypeResolver.Resolve(prop.Type, context).Declaration};");
                }
                sb.AppendLine(level, "}");

                //if (hasConsts)
                //{
                //    sb.AppendLine();
                //}
            }
            //else
            //{
            //    hasConsts = true;
            //}

            ////Static part
            //if (hasConsts
            //             //removing const support for now
            //             //If we enable it again, we should merge these members with KeysAndNames...
            //             && false
            //             ) {
            //	//https://github.com/Microsoft/TypeScript/issues/17372
            //	//Currently we can't merge namespaces and const enums.
            //	//This is supposed to be a bug.
            //	//Besides, even if this is fixed, I think enums will never be mergeable with interfaces,
            //	//so I think it will be always necessary to discriminate with something like $.
            //	//$ can't be used in C# classes, so will never happen a conflict.
            //	//We transpile C# Consts to TypeScript const enums because this is currently
            //	//the only way to inline values. Consts values direclty inside namespaces/modules are not inlined...
            //	//---R: Now, supporting only scoped types, maybe values dont need to be inlined...

            //	sb.AppendLine(level, $"export class {ClassName} {{");
            //	level++;
            //	foreach (var m in TypeSymbol.GetMembers()) {
            //		var fieldSymbol = (m as IFieldSymbol);
            //		if (fieldSymbol != null && fieldSymbol.IsConst) {
            //			//Consts names should not be changed, they are commonly uppercased both in client and server...
            //			var name = m.Name;
            //			sb.AppendLine(level, $"static readonly {name} = {JsonConvert.SerializeObject(fieldSymbol.ConstantValue)};");
            //		}
            //	}
            //	level--;
            //	sb.AppendLine(level, "}");
            //}


            level--;

            AppendKeysAndNames(sb);

            sb.Insert(0, context.GetImportsText());
            string content = sb.ToString();

            return(OutputFilePath, content);
        }
        internal static bool AreEquivalent(TypeSymbol a, TypeSymbol b, Compilation comp)
        {
            var aMembers = a.GetMembers().OfType<PropertySymbol>().ToList();
            var bMembers = b.GetMembers().OfType<PropertySymbol>().ToList();

            if (aMembers.Count != bMembers.Count) return false;

            for (var i = 0; i < aMembers.Count; i++)
            {
                var aMember = aMembers[i];
                var bMember = bMembers[i];

                if (aMember.Name != bMember.Name) return false;
                if (aMember.DeclaredAccessibility != bMember.DeclaredAccessibility) return false;

                var aType = aMember.Type;
                var bType = bMember.Type;

                var aName = aType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
                var bName = bType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);

                if (aName == bName) continue;

                var conv = comp.ClassifyConversion(aType, bType);

                if (!conv.IsIdentity) return false;
            }

            return true;
        }
Exemplo n.º 38
0
        protected void CheckStackSize(Value valueCount, EmitContext context)
        {
            using (context.InterruptAssignmentScope())
            {
                Value stack = context.RecursiveStackValue;
                BoundAccessExpression stackAccess = BoundAccessExpression.BindAccess(stack);
                Value stackAddr = context.RecursiveStackAddressValue;
                BoundAccessExpression stackAddrAccess = BoundAccessExpression.BindAccess(stackAddr);

                TypeSymbol arrayType = context.GetTypeSymbol(SpecialType.System_Array);

                context.Module.AddCommentTag("Stack size check");

                // Check stack size and double it if it's not enough
                // We know that doubling once will always be enough since the default size of the stack is the max number of stack values pushed in any method
                PropertySymbol arraySizeProperty = arrayType.GetMember <PropertySymbol>("Length", context);

                TypeSymbol intType = context.GetTypeSymbol(SpecialType.System_Int32);

                Value arraySize =
                    context.EmitValue(BoundAccessExpression.BindAccess(context, SyntaxNode, arraySizeProperty,
                                                                       stackAccess));
                BoundAccessExpression arraySizeAccess = BoundAccessExpression.BindAccess(arraySize);

                Value targetSize = context.EmitValue(CreateBoundInvocation(context, SyntaxNode,
                                                                           new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.Addition, intType, context), null,
                                                                           new BoundExpression[] { stackAddrAccess, BoundAccessExpression.BindAccess(valueCount) }));

                Value isSizeGreaterThan = context.EmitValue(CreateBoundInvocation(context, SyntaxNode,
                                                                                  new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.GreaterThanOrEqual, intType, context), null,
                                                                                  new BoundExpression[]
                {
                    BoundAccessExpression.BindAccess(targetSize),
                    arraySizeAccess,
                }));

                JumpLabel skipResizeLabel = context.Module.CreateLabel();

                context.Module.AddJumpIfFalse(skipResizeLabel, isSizeGreaterThan);

                // Resize logic
                Value constantTwo = context.GetConstantValue(intType, 2);
                Value newSize     = context.EmitValue(CreateBoundInvocation(context, SyntaxNode,
                                                                            new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.Multiplication, intType, context), null,
                                                                            new BoundExpression[]
                {
                    arraySizeAccess,
                    BoundAccessExpression.BindAccess(constantTwo),
                }));

                Value newArray = context.EmitValue(new BoundArrayCreationExpression(SyntaxNode, context,
                                                                                    context.GetTypeSymbol(SpecialType.System_Object).MakeArrayType(context),
                                                                                    new BoundExpression[] { BoundAccessExpression.BindAccess(newSize) }, null));

                MethodSymbol arrayCopyMethod = arrayType.GetMembers <MethodSymbol>("Copy", context)
                                               .First(e => e.Parameters.Length == 3 && e.Parameters[2].Type == intType);

                context.Emit(CreateBoundInvocation(context, null, arrayCopyMethod, null,
                                                   new BoundExpression[]
                {
                    stackAccess,
                    BoundAccessExpression.BindAccess(newArray),
                    BoundAccessExpression.BindAccess(arraySize)
                }));

                context.Module.AddCopy(newArray, stack);

                context.Module.LabelJump(skipResizeLabel);

                context.Module.AddCommentTag("Stack size check end");
            }
        }