FunctionEvaluation(MemberSymbol method, AbstractSymbolValueProvider baseValueProvider, Dictionary<DVariable, ISymbolValue> args)
        {
            vp = new InterpretationContext(baseValueProvider);

            foreach (var kv in args)
                vp[kv.Key] = kv.Value;
        }
        public static MemberSymbol FillMethodReturnType(MemberSymbol mr, ResolverContextStack ctxt)
        {
            if (mr == null || ctxt == null)
                return mr;

            var dm = mr.Definition as DMethod;

            ctxt.CurrentContext.IntroduceTemplateParameterTypes(mr);

            if (dm != null)
            {
                var returnType=GetMethodReturnType(dm, ctxt);
                mr = new MemberSymbol(dm, returnType, mr.DeclarationOrExpressionBase);
            }

            ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(mr);

            return mr;
        }
		ISemantic E(NewExpression nex)
		{
			// http://www.d-programming-language.org/expression.html#NewExpression
			ISemantic[] possibleTypes = null;

			if (nex.Type is IdentifierDeclaration)
				possibleTypes = TypeDeclarationResolver.Resolve((IdentifierDeclaration)nex.Type, ctxt, filterForTemplateArgs: false);
			else
				possibleTypes = TypeDeclarationResolver.Resolve(nex.Type, ctxt);
			
			var ctors = new Dictionary<DMethod, TemplateIntermediateType>();

			if (possibleTypes == null)
				return null;

			foreach (var t in possibleTypes)
			{
				var ct = DResolver.StripAliasSymbol(t as AbstractType) as TemplateIntermediateType;
				if (ct!=null && 
					!ct.Definition.ContainsAttribute(DTokens.Abstract))
					foreach (var ctor in GetConstructors(ct))
						ctors.Add(ctor, ct);
			}

			MemberSymbol finalCtor = null;

			var kvArray = ctors.ToArray();

			/*
			 * TODO: Determine argument types and filter out ctor overloads.
			 */

			if (kvArray.Length != 0)
				finalCtor = new MemberSymbol(kvArray[0].Key, kvArray[0].Value, nex);
			else if (possibleTypes.Length != 0)
				return AbstractType.Get(possibleTypes[0]);

			return finalCtor;
		}
        private static void GenerateForStatement(ScriptGenerator generator, MemberSymbol symbol, ForStatement statement)
        {
            if (statement.Body == null)
            {
                return;
            }

            ScriptTextWriter writer = generator.Writer;

            writer.Write("for ");
            writer.Write("(");
            if (statement.Initializers != null)
            {
                ExpressionGenerator.GenerateExpressionList(generator, symbol, statement.Initializers);
            }
            else if (statement.Variables != null)
            {
                GenerateVariableDeclarations(generator, symbol, statement.Variables);
            }
            writer.Write("; ");
            if (statement.Condition != null)
            {
                ExpressionGenerator.GenerateExpression(generator, symbol, statement.Condition);
            }
            writer.Write("; ");
            if (statement.Increments != null)
            {
                ExpressionGenerator.GenerateExpressionList(generator, symbol, statement.Increments);
            }
            writer.WriteLine(") {");
            writer.Indent++;
            GenerateStatement(generator, symbol, statement.Body);
            writer.Indent--;
            writer.Write("}");
            writer.WriteLine();
        }
        public void Visit(AdvancedReturnStatementNode node)
        {
            ValueAstEvaluator          valueEvaluator = new ValueAstEvaluator(sender);
            MathExpressionAstEvaluator exprEvaluator  = new MathExpressionAstEvaluator();
            Cell   cell = sender.GetCurrentCell();
            Symbol sym  = Stbl.st.Retrieve(node.Identifier.Label);

            if (sym is StateSymbol s)
            {
                try
                {
                    // Set state members
                    StateSymbol state = s.Copy();
                    foreach (ReturnMemberNode rNode in node.ReturnMembers)
                    {
                        MemberSymbol member = state.RetrieveMember(rNode.ID.Label);
                        switch (rNode.Value)
                        {
                        case ExpressionNode valueNode: member.SetValue(exprEvaluator.Visit(valueNode)); break;

                        case StringValueNode valueNode: member.SetValue(valueNode.Value); break;

                        default: throw new TheLanguageErrorException($"ReturnMember value cannot be of type \'{ rNode.Value.GetType().Name }\'");
                        }
                    }
                    sender.SetCell(cell, state);
                }
                catch (TheLanguageErrorException e) { throw new TheLanguageErrorException($"Return statement \'{ node.Identifier.Label }\'", e); }
            }
            else
            {
                throw new TheLanguageErrorException($"Return statement. Unexpected type { sym } expected State");
            }

            sender.ReturnStatementHasBeenHit = true;
        }
Exemple #6
0
        public static AbstractType DemangleAndResolve(string mangledString, ResolutionContext ctxt, out ITypeDeclaration qualifier)
        {
            bool isCFunction;

            Demangler.Demangle(mangledString, out qualifier, out isCFunction);

            // Seek for C functions | Functions that have no direct module association (e.g. _Dmain)
            if (qualifier is IdentifierDeclaration && qualifier.InnerDeclaration == null)
            {
                var id = (qualifier as IdentifierDeclaration).Id;
                return(Resolver.ASTScanner.NameScan.ScanForCFunction(ctxt, id, isCFunction));
            }

            bool seekCtor = false;

            if (qualifier is IdentifierDeclaration)
            {
                var id = (qualifier as IdentifierDeclaration).Id;
                if ((seekCtor = (id == DMethod.ConstructorIdentifier)) || id == "__Class" || id == "__ModuleInfo")
                {
                    qualifier = qualifier.InnerDeclaration;
                }
            }

            var resSym = TypeDeclarationResolver.ResolveSingle(qualifier, ctxt);

            if (seekCtor && resSym is UserDefinedType)
            {
                var ctor = (resSym as TemplateIntermediateType).Definition[DMethod.ConstructorIdentifier].FirstOrDefault();
                if (ctor != null)
                {
                    resSym = new MemberSymbol(ctor as DNode, null, null);
                }
            }
            return(resSym);
        }
Exemple #7
0
        private static void GenerateWhileStatement(ScriptGenerator generator, MemberSymbol symbol,
                                                   WhileStatement statement)
        {
            if (statement.Body == null)
            {
                return;
            }

            ScriptTextWriter writer = generator.Writer;

            if (statement.PreCondition)
            {
                writer.Write("while (");
                ExpressionGenerator.GenerateExpression(generator, symbol, statement.Condition);
                writer.WriteLine(") {");
            }
            else
            {
                writer.WriteLine("do {");
            }

            writer.Indent++;
            GenerateStatement(generator, symbol, statement.Body);
            writer.Indent--;

            if (statement.PreCondition)
            {
                writer.WriteLine("}");
            }
            else
            {
                writer.Write("} while (");
                ExpressionGenerator.GenerateExpression(generator, symbol, statement.Condition);
                writer.WriteLine(");");
            }
        }
        private static void GenerateBaseInitializerExpression(ScriptGenerator generator, MemberSymbol symbol,
                                                              BaseInitializerExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            Debug.Assert(symbol.Parent is ClassSymbol);

            ClassSymbol baseClass = ((ClassSymbol)symbol.Parent).BaseClass;

            Debug.Assert(baseClass != null);

            if (baseClass.GenericArguments?.Any() ?? false)
            {
                writer.Write(DSharpStringResources.ScriptExportMember("getGenericConstructor"));
                writer.Write("(");
                writer.Write(baseClass.FullGeneratedName);
                writer.Write(", ");
                generator.WriteGenericTypeArgumentsMap(baseClass.GenericArguments, baseClass.GenericParameters);
                writer.Write(")");
            }
            else
            {
                writer.Write(baseClass.FullGeneratedName);
            }

            writer.Write(".call(this");

            if (expression.Parameters != null)
            {
                writer.Write(", ");
                GenerateExpressionList(generator, symbol, expression.Parameters);
            }

            writer.Write(")");
        }
		/// <summary>
		/// The variable's or method's base type will be resolved (if auto type, the intializer's type will be taken).
		/// A class' base class will be searched.
		/// etc..
		/// </summary>
		public static AbstractType HandleNodeMatch(
			INode m,
			ResolutionContext ctxt,
			AbstractType resultBase = null,
			object typeBase = null)
		{
			AbstractType ret = null;

			// See https://github.com/aBothe/Mono-D/issues/161
			int stkC;

			if (stackCalls == null)
			{
				stackCalls = new Dictionary<INode, int>();
				stackCalls[m] = stkC = 1;
			}
			else if (stackCalls.TryGetValue(m, out stkC))
				stackCalls[m] = ++stkC;
			else
				stackCalls[m] = stkC = 1;
			/*
			 * Pushing a new scope is only required if current scope cannot be found in the handled node's hierarchy.
			 * Edit: No, it is required nearly every time because of nested type declarations - then, we do need the 
			 * current block scope.
			 */
			bool popAfterwards;
			{
				var newScope = m is IBlockNode ? (IBlockNode)m : m.Parent as IBlockNode;
				popAfterwards = ctxt.ScopedBlock != newScope && newScope != null;
				if (popAfterwards) {
					var options = ctxt.CurrentContext.ContextDependentOptions;
					var applyOptions = ctxt.ScopedBlockIsInNodeHierarchy (m);
					ctxt.PushNewScope (newScope);
					if (applyOptions)
						ctxt.CurrentContext.ContextDependentOptions = options;
				}
			}

			var canResolveBase = ((ctxt.Options & ResolutionOptions.DontResolveBaseTypes) != ResolutionOptions.DontResolveBaseTypes) && 
			                     stkC < 10 && (m.Type == null || m.Type.ToString(false) != m.Name);
			
			// To support resolving type parameters to concrete types if the context allows this, introduce all deduced parameters to the current context
			if (resultBase is DSymbol)
				ctxt.CurrentContext.IntroduceTemplateParameterTypes((DSymbol)resultBase);

			var importSymbolNode = m as ImportSymbolNode;
			var variable = m as DVariable;

			// Only import symbol aliases are allowed to search in the parse cache
			if (importSymbolNode != null)
				ret = HandleImportSymbolMatch (importSymbolNode,ctxt);
			else if (variable != null)
			{
				AbstractType bt = null;

				if (!(variable is EponymousTemplate)) {
					if (canResolveBase) {
						var bts = TypeDeclarationResolver.Resolve (variable.Type, ctxt);
						ctxt.CheckForSingleResult (bts, variable.Type);

						if (bts != null && bts.Length != 0)
							bt = bts [0];

					// For auto variables, use the initializer to get its type
					else if (variable.Initializer != null) {
							bt = DResolver.StripMemberSymbols (Evaluation.EvaluateType (variable.Initializer, ctxt));
						}

						// Check if inside an foreach statement header
						if (bt == null && ctxt.ScopedStatement != null)
							bt = GetForeachIteratorType (variable, ctxt);
					}

					// Note: Also works for aliases! In this case, we simply try to resolve the aliased type, otherwise the variable's base type
					ret = variable.IsAlias ?
					new AliasedType (variable, bt, typeBase as ISyntaxRegion) as MemberSymbol :
					new MemberSymbol (variable, bt, typeBase as ISyntaxRegion);
				} else
					ret = new EponymousTemplateType (variable as EponymousTemplate, GetInvisibleTypeParameters(variable, ctxt).AsReadOnly(), typeBase as ISyntaxRegion);
			}
			else if (m is DMethod)
			{
				ret = new MemberSymbol(m as DNode,canResolveBase ? GetMethodReturnType(m as DMethod, ctxt) : null, typeBase as ISyntaxRegion);
			}
			else if (m is DClassLike)
				ret = HandleClassLikeMatch (m as DClassLike, ctxt, typeBase, canResolveBase);
			else if (m is DModule)
			{
				var mod = (DModule)m;
				if (typeBase != null && typeBase.ToString() != mod.ModuleName)
				{
					var pack = ctxt.ParseCache.LookupPackage(typeBase.ToString()).FirstOrDefault();
					if (pack != null)
						ret = new PackageSymbol(pack, typeBase as ISyntaxRegion);
				}
				else
					ret = new ModuleSymbol(m as DModule, typeBase as ISyntaxRegion);
			}
			else if (m is DEnum)
				ret = new EnumType((DEnum)m, typeBase as ISyntaxRegion);
			else if (m is TemplateParameter.Node)
			{
				//ResolveResult[] templateParameterType = null;

				//TODO: Resolve the specialization type
				//var templateParameterType = TemplateInstanceHandler.ResolveTypeSpecialization(tmp, ctxt);
				ret = new TemplateParameterSymbol((m as TemplateParameter.Node).TemplateParameter, null, typeBase as ISyntaxRegion);
			}
			else if(m is NamedTemplateMixinNode)
			{
				var tmxNode = m as NamedTemplateMixinNode;
				ret = new MemberSymbol(tmxNode, canResolveBase ? ResolveSingle(tmxNode.Type, ctxt) : null, typeBase as ISyntaxRegion);
			}

			if (popAfterwards)
				ctxt.Pop();
			else if (resultBase is DSymbol)
				ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals((DSymbol)resultBase);

			if (stkC == 1)
				stackCalls.Remove(m);
			else
				stackCalls[m] = stkC-1;

			return ret;
		}
        static AbstractType DeduceEponymousTemplate(EponymousTemplateType ept, ResolutionContext ctxt)
        {
            if (ept.Definition.Initializer == null) {
                ctxt.LogError (ept.Definition, "Can't deduce type from empty initializer!");
                return null;
            }

            // Introduce the deduced params to the current resolution context
            ctxt.CurrentContext.IntroduceTemplateParameterTypes(ept);

            // Get actual overloads
            AbstractType deducedType = null;

            deducedType = new MemberSymbol (ept.Definition, Evaluation.EvaluateType (ept.Definition.Initializer, ctxt), null, ept.DeducedTypes); //ept; //Evaluation.EvaluateType (ept.Definition.Initializer, ctxt);

            // Undo context-related changes
            ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ept);

            return deducedType;
        }
        private static void GenerateMethodExpression(ScriptGenerator generator, MemberSymbol symbol, MethodExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            if (expression.Method.SkipGeneration)
            {
                // If this method is to be skipped from generation, just generate the
                // left-hand-side object reference, and skip everything past it, including
                // the dot.

                GenerateExpression(generator, symbol, expression.ObjectReference);
                return;
            }

            if (expression.ObjectReference is BaseExpression)
            {
                Debug.Assert(expression.Method.IsExtension == false);

                writer.Write(((BaseExpression)expression.ObjectReference).EvaluatedType.FullGeneratedName);
                writer.Write(".prototype.");
                writer.Write(expression.Method.GeneratedName);
                writer.Write(".call(");
                writer.Write(generator.CurrentImplementation.ThisIdentifier);
                if ((expression.Parameters != null) && (expression.Parameters.Count != 0))
                {
                    writer.Write(", ");
                    GenerateExpressionList(generator, symbol, expression.Parameters);
                }
                writer.Write(")");
            }
            else
            {
                if (expression.Method.IsAliased)
                {
                    writer.Write(expression.Method.Alias);
                    writer.Write("(");
                    if ((expression.Method.Visibility & MemberVisibility.Static) == 0)
                    {
                        GenerateExpression(generator, symbol, expression.ObjectReference);
                        if ((expression.Parameters != null) && (expression.Parameters.Count != 0))
                        {
                            writer.Write(", ");
                        }
                    }
                    if ((expression.Parameters != null) && (expression.Parameters.Count != 0))
                    {
                        GenerateExpressionList(generator, symbol, expression.Parameters);
                    }
                    writer.Write(")");
                }
                else
                {
                    if (expression.Method.IsExtension)
                    {
                        Debug.Assert(expression.Method.Parent.Type == SymbolType.Class);

                        string extendee = ((ClassSymbol)expression.Method.Parent).Extendee;
                        Debug.Assert(String.IsNullOrEmpty(extendee) == false);

                        writer.Write(extendee);
                        writer.Write(".");
                    }
                    else
                    {
                        GenerateExpression(generator, symbol, expression.ObjectReference);
                        if (expression.Method.GeneratedName.Length != 0)
                        {
                            writer.Write(".");
                        }
                    }

                    if (expression.Method.GeneratedName.Length != 0)
                    {
                        writer.Write(expression.Method.GeneratedName);
                    }
                    writer.Write("(");
                    if (expression.Parameters != null)
                    {
                        GenerateExpressionList(generator, symbol, expression.Parameters);
                    }
                    writer.Write(")");
                }
            }
        }
        private static void GenerateLateBoundExpression(ScriptGenerator generator, MemberSymbol symbol, LateBoundExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;
            string           name   = null;

            LiteralExpression literalNameExpression = expression.NameExpression as LiteralExpression;

            if ((literalNameExpression != null) && (literalNameExpression.Value is string))
            {
                name = (string)literalNameExpression.Value;
                Debug.Assert(String.IsNullOrEmpty(name) == false);
            }

            if (expression.Operation == LateBoundOperation.DeleteField)
            {
                writer.Write("delete ");
            }

            if (expression.Operation == LateBoundOperation.GetScriptType)
            {
                writer.Write("typeof(");
            }
            else if (expression.Operation == LateBoundOperation.HasMethod)
            {
                writer.Write("(typeof(");
            }
            else if (expression.Operation == LateBoundOperation.HasField)
            {
                writer.Write("(");
                GenerateExpression(generator, symbol, expression.NameExpression);
                writer.Write(" in ");
            }

            if (expression.ObjectReference != null)
            {
                GenerateExpression(generator, symbol, expression.ObjectReference);
            }

            switch (expression.Operation)
            {
            case LateBoundOperation.InvokeMethod:
                if (Utility.IsValidIdentifier(name))
                {
                    if (expression.ObjectReference != null)
                    {
                        writer.Write(".");
                    }
                    writer.Write(name);
                }
                else
                {
                    writer.Write("[");
                    GenerateExpression(generator, symbol, expression.NameExpression);
                    writer.Write("]");
                }

                writer.Write("(");
                if (expression.Parameters.Count != 0)
                {
                    GenerateExpressionList(generator, symbol, expression.Parameters);
                }
                writer.Write(")");

                break;

            case LateBoundOperation.GetField:
                if (Utility.IsValidIdentifier(name))
                {
                    writer.Write(".");
                    writer.Write(name);
                }
                else
                {
                    writer.Write("[");
                    GenerateExpression(generator, symbol, expression.NameExpression);
                    writer.Write("]");
                }
                break;

            case LateBoundOperation.SetField:
                if (Utility.IsValidIdentifier(name))
                {
                    writer.Write(".");
                    writer.Write(name);
                }
                else
                {
                    writer.Write("[");
                    GenerateExpression(generator, symbol, expression.NameExpression);
                    writer.Write("]");
                }

                writer.Write(" = ");
                GenerateExpressionList(generator, symbol, expression.Parameters);
                break;

            case LateBoundOperation.DeleteField:
                if (Utility.IsValidIdentifier(name))
                {
                    writer.Write(".");
                    writer.Write(name);
                }
                else
                {
                    writer.Write("[");
                    GenerateExpression(generator, symbol, expression.NameExpression);
                    writer.Write("]");
                }
                break;

            case LateBoundOperation.GetScriptType:
                writer.Write(")");
                break;

            case LateBoundOperation.HasField:
                writer.Write(")");
                break;

            case LateBoundOperation.HasMethod:
                if (Utility.IsValidIdentifier(name))
                {
                    if (expression.ObjectReference != null)
                    {
                        writer.Write(".");
                    }
                    writer.Write(name);
                }
                else
                {
                    writer.Write("[");
                    GenerateExpression(generator, symbol, expression.NameExpression);
                    writer.Write("]");
                }

                writer.Write(") === 'function')");
                break;
            }
        }
        private static void GenerateExpressionListAsNameValuePairs(ScriptGenerator generator, MemberSymbol symbol, ICollection <Expression> expressions)
        {
            Debug.Assert(expressions.Count % 2 == 0);

            ScriptTextWriter writer = generator.Writer;

            bool firstExpression = true;
            bool valueExpression = false;

            foreach (Expression expression in expressions)
            {
                if ((firstExpression == false) && (valueExpression == false))
                {
                    writer.Write(", ");
                }

                if (valueExpression)
                {
                    writer.Write(": ");
                    GenerateExpression(generator, symbol, expression);

                    valueExpression = false;
                }
                else
                {
                    Debug.Assert(expression.Type == ExpressionType.Literal);
                    Debug.Assert(((LiteralExpression)expression).Value is string);

                    string name = (string)((LiteralExpression)expression).Value;

                    if (Utility.IsValidIdentifier(name))
                    {
                        writer.Write(name);
                    }
                    else
                    {
                        writer.Write(Utility.QuoteString(name));
                    }

                    valueExpression = true;
                }

                firstExpression = false;
            }
        }
Exemple #14
0
        private static void GenerateVariableDeclarationStatement(ScriptGenerator generator, MemberSymbol symbol,
                                                                 VariableDeclarationStatement statement)
        {
            ScriptTextWriter writer = generator.Writer;

            GenerateVariableDeclarations(generator, symbol, statement);
            writer.WriteLine(";");
        }
Exemple #15
0
		void HandleMethod(DMethod dm, MemberSymbol alreadyResolvedMethod = null)
		{
			if (dm != null && dm.Parameters.Count > 0 && dm.Parameters[0].Type != null)
			{
				var loc = dm.Body != null ? dm.Body.Location : dm.Location;
				using (alreadyResolvedMethod != null ? ctxt.Push(alreadyResolvedMethod, loc) : ctxt.Push(dm, loc))
				{
					var t = TypeDeclarationResolver.ResolveSingle(dm.Parameters[0].Type, ctxt);
					if (ResultComparer.IsImplicitlyConvertible(firstArgument, t, ctxt))
					{
						var res = alreadyResolvedMethod ?? TypeDeclarationResolver.HandleNodeMatch(dm, ctxt, typeBase: sr);
						res.Tag(UfcsTag.Id, new UfcsTag { firstArgument = firstArgument });
						matches.Add(res);
					}
				}
			}
		}
Exemple #16
0
        private void BuildMembers(TypeSymbol typeSymbol)
        {
            if (typeSymbol.Type == SymbolType.Delegate)
            {
                DelegateTypeNode delegateNode = (DelegateTypeNode)typeSymbol.ParseContext;

                TypeSymbol returnType = typeSymbol.SymbolSet.ResolveType(delegateNode.ReturnType, _symbolTable, typeSymbol);
                Debug.Assert(returnType != null);

                if (returnType != null)
                {
                    MethodSymbol invokeMethod = new MethodSymbol("Invoke", typeSymbol, returnType, MemberVisibility.Public);
                    invokeMethod.SetTransformedName(String.Empty);

                    // Mark the method as abstract, as there is no actual implementation of the method
                    // to be generated
                    invokeMethod.SetImplementationState(SymbolImplementationFlags.Abstract);

                    typeSymbol.AddMember(invokeMethod);
                }
                return;
            }

            CustomTypeNode typeNode = (CustomTypeNode)typeSymbol.ParseContext;

            foreach (MemberNode member in typeNode.Members)
            {
                MemberSymbol memberSymbol = null;
                switch (member.NodeType)
                {
                case ParseNodeType.FieldDeclaration:
                case ParseNodeType.ConstFieldDeclaration:
                    memberSymbol = BuildField((FieldDeclarationNode)member, typeSymbol);
                    break;

                case ParseNodeType.PropertyDeclaration:
                    memberSymbol = BuildPropertyAsField((PropertyDeclarationNode)member, typeSymbol);
                    if (memberSymbol == null)
                    {
                        memberSymbol = BuildProperty((PropertyDeclarationNode)member, typeSymbol);
                    }
                    break;

                case ParseNodeType.IndexerDeclaration:
                    memberSymbol = BuildIndexer((IndexerDeclarationNode)member, typeSymbol);
                    break;

                case ParseNodeType.ConstructorDeclaration:
                case ParseNodeType.MethodDeclaration:
                    if ((member.Modifiers & Modifiers.Extern) != 0)
                    {
                        // Extern methods are there for defining overload signatures, so
                        // we just skip them as far as metadata goes. The validator has
                        // taken care of the requirements/constraints around use of extern methods.
                        continue;
                    }
                    memberSymbol = BuildMethod((MethodDeclarationNode)member, typeSymbol);
                    break;

                case ParseNodeType.EventDeclaration:
                    memberSymbol = BuildEvent((EventDeclarationNode)member, typeSymbol);
                    break;

                case ParseNodeType.EnumerationFieldDeclaration:
                    memberSymbol = BuildEnumField((EnumerationFieldNode)member, typeSymbol);
                    break;
                }

                if (memberSymbol != null)
                {
                    memberSymbol.SetParseContext(member);

                    if ((typeSymbol.IsApplicationType == false) &&
                        ((memberSymbol.Type == SymbolType.Constructor) ||
                         (typeSymbol.GetMember(memberSymbol.Name) != null)))
                    {
                        // If the type is an imported type, then it is allowed to contain
                        // overloads, and we're simply going to ignore its existence, as long
                        // as one overload has been added to the member table.
                        continue;
                    }

                    typeSymbol.AddMember(memberSymbol);

                    if ((typeSymbol.Type == SymbolType.Class) && (memberSymbol.Type == SymbolType.Event))
                    {
                        EventSymbol eventSymbol = (EventSymbol)memberSymbol;
                        if (eventSymbol.DefaultImplementation)
                        {
                            // Add a private field that will serve as the backing member
                            // later on in the conversion (eg. in non-event expressions)
                            MemberVisibility visibility = MemberVisibility.PrivateInstance;
                            if ((eventSymbol.Visibility & MemberVisibility.Static) != 0)
                            {
                                visibility |= MemberVisibility.Static;
                            }

                            FieldSymbol fieldSymbol =
                                new FieldSymbol("__" + Utility.CreateCamelCaseName(eventSymbol.Name), typeSymbol,
                                                eventSymbol.AssociatedType);
                            fieldSymbol.SetVisibility(visibility);
                            fieldSymbol.SetParseContext(((EventDeclarationNode)eventSymbol.ParseContext).Field);

                            typeSymbol.AddMember(fieldSymbol);
                        }
                    }
                }
            }
        }
		public static ISymbolValue Execute(MemberSymbol method, ISymbolValue[] arguments, AbstractSymbolValueProvider vp)
		{
			return new ErrorValue(new EvaluationException("CTFE is not implemented yet."));
		}
        static AbstractType DeduceEponymousTemplate(EponymousTemplateType ept, ResolutionContext ctxt)
        {
            if (ept.Definition.Initializer == null &&
                ept.Definition.Type == null) {
                ctxt.LogError(ept.Definition, "Can't deduce type from empty initializer!");
                return null;
            }

            // Introduce the deduced params to the current resolution context
            ctxt.CurrentContext.IntroduceTemplateParameterTypes(ept);

            // Get actual overloads
            AbstractType deducedType = null;
            var def = ept.Definition;
            deducedType = new MemberSymbol(def, def.Type != null ?
                TypeDeclarationResolver.ResolveSingle(def.Type, ctxt) :
                ExpressionTypeEvaluation.EvaluateType(def.Initializer, ctxt), null, ept.DeducedTypes); //ept; //ExpressionTypeEvaluation.EvaluateType (ept.Definition.Initializer, ctxt);

            deducedType.Tag = ept.Tag; // Currently requried for proper UFCS resolution - sustain ept's Tag

            // Undo context-related changes
            ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ept);

            return deducedType;
        }
        static void HandleDMethodOverload(ResolutionContext ctxt, bool eval, ISymbolValue baseValue, List <ISemantic> callArguments, bool returnBaseTypeOnly, List <AbstractType> argTypeFilteredOverloads, ref bool hasHandledUfcsResultBefore,
                                          MemberSymbol ms, ref AbstractType untemplatedMethod)
        {
            var dm = ms.Definition as DMethod;

            if (dm == null)
            {
                return;
            }



            ISemantic firstUfcsArg;
            bool      isUfcs = UFCSResolver.IsUfcsResult(ms, out firstUfcsArg);

            // In the case of an ufcs, insert the first argument into the CallArguments list
            if (isUfcs && !hasHandledUfcsResultBefore)
            {
                callArguments.Insert(0, eval ? baseValue as ISemantic : firstUfcsArg);
                hasHandledUfcsResultBefore = true;
            }
            else if (!isUfcs && hasHandledUfcsResultBefore)             // In the rare case of having a ufcs result occuring _after_ a normal member result, remove the initial arg again
            {
                callArguments.RemoveAt(0);
                hasHandledUfcsResultBefore = false;
            }

            if (dm.Parameters.Count == 0 && callArguments.Count > 0)
            {
                return;
            }

            var deducedTypeDict        = new DeducedTypeDictionary(ms);
            var templateParamDeduction = new TemplateParameterDeduction(deducedTypeDict, ctxt);

            var back = ctxt.ScopedBlock;

            using (ctxt.Push(ms))
            {
                if (ctxt.ScopedBlock != back)
                {
                    ctxt.CurrentContext.DeducedTemplateParameters = deducedTypeDict;
                }

                bool add        = true;
                int  currentArg = 0;
                if (dm.Parameters.Count > 0 || callArguments.Count > 0)
                {
                    bool hadDTuples = false;
                    for (int i = 0; i < dm.Parameters.Count; i++)
                    {
                        var paramType = dm.Parameters[i].Type;

                        // Handle the usage of tuples: Tuples may only be used as as-is, so not as an array, pointer or in a modified way..
                        if (paramType is IdentifierDeclaration &&
                            (hadDTuples |= TryHandleMethodArgumentTuple(ctxt, ref add, callArguments, dm, deducedTypeDict, i, ref currentArg)))
                        {
                            continue;
                        }
                        else if (currentArg < callArguments.Count)
                        {
                            if (!(add = templateParamDeduction.HandleDecl(null, paramType, callArguments[currentArg++])))
                            {
                                break;
                            }
                        }
                        else
                        {
                            // If there are more parameters than arguments given, check if the param has default values
                            add = !(dm.Parameters[i] is DVariable) || (dm.Parameters[i] as DVariable).Initializer != null;

                            // Assume that all further method parameters do have default values - and don't check further parameters
                            break;
                        }
                    }

                    // Too few args
                    if (!hadDTuples && currentArg < callArguments.Count)
                    {
                        add = false;
                    }
                }

                if (!add)
                {
                    return;
                }

                // If type params were unassigned, try to take the defaults
                if (dm.TemplateParameters != null)
                {
                    foreach (var tpar in dm.TemplateParameters)
                    {
                        if (deducedTypeDict[tpar] == null && !templateParamDeduction.Handle(tpar, null))
                        {
                            return;
                        }
                    }
                }

                if (deducedTypeDict.AllParamatersSatisfied)
                {
                    ms.DeducedTypes = deducedTypeDict.ToReadonly();
                    var bt = TypeDeclarationResolver.GetMethodReturnType(dm, ctxt) ?? ms.Base;

                    if (eval || !returnBaseTypeOnly)
                    {
                        bt = new MemberSymbol(dm, bt, ms.DeclarationOrExpressionBase, ms.DeducedTypes)
                        {
                            Tag = ms.Tag
                        }
                    }
                    ;

                    if (dm.TemplateParameters == null || dm.TemplateParameters.Length == 0)
                    {
                        untemplatedMethod = bt;                         //ISSUE: Have another state that indicates an ambiguous non-templated method matching.
                    }
                    argTypeFilteredOverloads.Add(bt);
                }
            }
        }
Exemple #20
0
        public static void GenerateStatement(ScriptGenerator generator, MemberSymbol symbol, Statement statement)
        {
            switch (statement.Type)
            {
            case StatementType.Block:
                GenerateBlockStatement(generator, symbol, (BlockStatement)statement);

                break;

            case StatementType.Empty:

                break;

            case StatementType.VariableDeclaration:
                GenerateVariableDeclarationStatement(generator, symbol, (VariableDeclarationStatement)statement);

                break;

            case StatementType.Return:
                GenerateReturnStatement(generator, symbol, (ReturnStatement)statement);

                break;

            case StatementType.Expression:
                GenerateExpressionStatement(generator, symbol, (ExpressionStatement)statement);

                break;

            case StatementType.IfElse:
                GenerateIfElseStatement(generator, symbol, (IfElseStatement)statement);

                break;

            case StatementType.While:
                GenerateWhileStatement(generator, symbol, (WhileStatement)statement);

                break;

            case StatementType.For:
                GenerateForStatement(generator, symbol, (ForStatement)statement);

                break;

            case StatementType.ForIn:
                GenerateForInStatement(generator, symbol, (ForInStatement)statement);

                break;

            case StatementType.Switch:
                GenerateSwitchStatement(generator, symbol, (SwitchStatement)statement);

                break;

            case StatementType.Break:
                GenerateBreakStatement(generator, symbol, (BreakStatement)statement);

                break;

            case StatementType.Continue:
                GenerateContinueStatement(generator, symbol, (ContinueStatement)statement);

                break;

            case StatementType.Throw:
                GenerateThrowStatement(generator, symbol, (ThrowStatement)statement);

                break;

            case StatementType.TryCatchFinally:
                GenerateTryCatchFinallyStatement(generator, symbol, (TryCatchFinallyStatement)statement);

                break;

            case StatementType.Error:
                GenerateErrorStatement(generator, symbol, (ErrorStatement)statement);

                break;

            case StatementType.Using:
                GenerateUsingStatement(generator, symbol, (UsingStatement)statement);

                break;

            default:
                Debug.Fail("Unexpected statement type: " + statement.Type);

                break;
            }
        }
Exemple #21
0
        StatementSyntax GenerateTestStmtNullableValueTypeMember(MemberSymbol memberSymbol)
        {
            var memberName = memberSymbol.GetName();

            return(IfStatement(
                       BinaryExpression(
                           SyntaxKind.LogicalAndExpression,
                           BinaryExpression(
                               SyntaxKind.NotEqualsExpression,
                               IdentifierName(memberName),
                               LiteralExpression(SyntaxKind.NullLiteralExpression)
                               ),
                           BinaryExpression(
                               SyntaxKind.NotEqualsExpression,
                               MemberAccessExpression(
                                   SyntaxKind.SimpleMemberAccessExpression,
                                   IdentifierName("other"),
                                   IdentifierName(memberName)
                                   ),
                               LiteralExpression(SyntaxKind.NullLiteralExpression)
                               )
                           ),
                       Block(SingletonList <StatementSyntax>(
                                 IfStatement(
                                     PrefixUnaryExpression(
                                         SyntaxKind.LogicalNotExpression,
                                         InvocationExpression(
                                             MemberAccessExpression(
                                                 SyntaxKind.SimpleMemberAccessExpression,
                                                 MemberAccessExpression(
                                                     SyntaxKind.SimpleMemberAccessExpression,
                                                     IdentifierName(memberName),
                                                     IdentifierName("Value")
                                                     ),
                                                 IdentifierName("Equals")
                                                 )
                                             ).WithArgumentList(ArgumentList(SingletonSeparatedList <ArgumentSyntax>(Argument(
                                                                                                                         MemberAccessExpression(
                                                                                                                             SyntaxKind.SimpleMemberAccessExpression,
                                                                                                                             MemberAccessExpression(
                                                                                                                                 SyntaxKind.SimpleMemberAccessExpression,
                                                                                                                                 IdentifierName("other"),
                                                                                                                                 IdentifierName(memberName)
                                                                                                                                 ),
                                                                                                                             IdentifierName("Value")
                                                                                                                             )
                                                                                                                         ))))
                                         ),
                                     ReturnStatement(LiteralExpression(SyntaxKind.FalseLiteralExpression))
                                     )
                                 ))
                       ).WithElse(ElseClause(
                                      IfStatement(
                                          BinaryExpression(
                                              SyntaxKind.LogicalOrExpression,
                                              BinaryExpression(
                                                  SyntaxKind.NotEqualsExpression,
                                                  IdentifierName(memberName),
                                                  LiteralExpression(SyntaxKind.NullLiteralExpression)
                                                  ),
                                              BinaryExpression(
                                                  SyntaxKind.NotEqualsExpression,
                                                  MemberAccessExpression(
                                                      SyntaxKind.SimpleMemberAccessExpression,
                                                      IdentifierName("other"),
                                                      IdentifierName(memberName)
                                                      ),
                                                  LiteralExpression(SyntaxKind.NullLiteralExpression)
                                                  )
                                              ),
                                          ReturnStatement(LiteralExpression(SyntaxKind.FalseLiteralExpression))
                                          )
                                      )));
        }
        /// <summary>
        /// The variable's or method's base type will be resolved (if auto type, the intializer's type will be taken).
        /// A class' base class will be searched.
        /// etc..
        /// </summary>
        public static AbstractType HandleNodeMatch(
			INode m,
			ResolverContextStack ctxt,
			AbstractType resultBase = null,
			object typeBase = null)
        {
            stackNum_HandleNodeMatch++;

            bool popAfterwards = m.Parent != ctxt.ScopedBlock && m.Parent is IBlockNode;
            if (popAfterwards)
                ctxt.PushNewScope((IBlockNode)m.Parent);

            //HACK: Really dirty stack overflow prevention via manually counting call depth
            var canResolveBaseGenerally = stackNum_HandleNodeMatch < 6;

            var DoResolveBaseType = canResolveBaseGenerally &&
                !ctxt.Options.HasFlag(ResolutionOptions.DontResolveBaseClasses) &&
                (m.Type == null || m.Type.ToString(false) != m.Name);

            AbstractType ret = null;

            // To support resolving type parameters to concrete types if the context allows this, introduce all deduced parameters to the current context
            if (canResolveBaseGenerally && resultBase is DSymbol)
                ctxt.CurrentContext.IntroduceTemplateParameterTypes((DSymbol)resultBase);

            // Only import symbol aliases are allowed to search in the parse cache
            if (m is ImportSymbolAlias)
            {
                var isa = (ImportSymbolAlias)m;

                if (isa.IsModuleAlias ? isa.Type != null : isa.Type.InnerDeclaration != null)
                {
                    var mods = new List<DModule>();
                    var td=isa.IsModuleAlias ? isa.Type : isa.Type.InnerDeclaration;
                    foreach (var mod in ctxt.ParseCache.LookupModuleName(td.ToString()))
                        mods.Add(mod as DModule);

                    if(mods.Count == 0)
                            ctxt.LogError(new NothingFoundError(isa.Type));
                    else if(mods.Count > 1)
                    {
                        var m__=new List<ISemantic>();

                        foreach(var mod in mods)
             							m__.Add(new ModuleSymbol(mod, isa.Type));

                        ctxt.LogError(new AmbiguityError(isa.Type,m__));
                    }

                    var bt=mods.Count != 0 ? (AbstractType)new ModuleSymbol(mods[0], td) : null;

                    //TODO: Is this correct behaviour?
                    if (!isa.IsModuleAlias){
                        var furtherId = ResolveFurtherTypeIdentifier(isa.Type.ToString(false), new[]{ bt }, ctxt, isa.Type);

                        ctxt.CheckForSingleResult(furtherId, isa.Type);

                        if (furtherId != null && furtherId.Length != 0)
                            bt = furtherId[0];
                        else
                            bt = null;
                    }

                    ret = new AliasedType(isa, bt, isa.Type);
                }
            }
            else if (m is DVariable)
            {
                var v = (DVariable)m;
                AbstractType bt = null;

                if (DoResolveBaseType)
                {
                    var bts = TypeDeclarationResolver.Resolve(v.Type, ctxt);

                    if (bts != null && bts.Length != 0 && ctxt.CheckForSingleResult(bts, v.Type))
                        bt = bts[0];

                    // For auto variables, use the initializer to get its type
                    else if (v.Initializer != null)
                        bt = ExpressionSemantics.Evaluation.EvaluateType(v.Initializer, ctxt);

                    // Check if inside an foreach statement header
                    if (bt == null && ctxt.ScopedStatement != null)
                        bt = GetForeachIteratorType(v, ctxt);
                }

                // Note: Also works for aliases! In this case, we simply try to resolve the aliased type, otherwise the variable's base type
                ret=v.IsAlias ?
                    (DSymbol)new AliasedType(v, bt, typeBase as ISyntaxRegion) :
                    new MemberSymbol(v, bt, typeBase as ISyntaxRegion);
            }
            else if (m is DMethod)
            {
                ret = new MemberSymbol((DNode)m,
                    DoResolveBaseType ? GetMethodReturnType((DMethod)m, ctxt) : null
                    , typeBase as ISyntaxRegion);
            }
            else if (m is DClassLike)
            {
                UserDefinedType udt = null;
                var dc=(DClassLike)m;

                switch (dc.ClassType)
                {
                    case DTokens.Struct:
                        udt = new StructType(dc, typeBase as ISyntaxRegion);
                        break;
                    case DTokens.Union:
                        udt = new UnionType(dc, typeBase as ISyntaxRegion);
                        break;
                    case DTokens.Class:
                        udt = new ClassType(dc, typeBase as ISyntaxRegion, null);
                        break;
                    case DTokens.Template:
                        udt = new TemplateType(dc, typeBase as ISyntaxRegion);
                        break;
                    case DTokens.Interface:
                        udt = new InterfaceType(dc, typeBase as ISyntaxRegion);
                        break;
                    default:
                        ctxt.LogError(new ResolutionError(m, "Unknown type ("+DTokens.GetTokenString(dc.ClassType)+")"));
                        break;
                }

                if (canResolveBaseGenerally && !ctxt.Options.HasFlag(ResolutionOptions.DontResolveBaseClasses))
                    ret = DResolver.ResolveBaseClasses(udt, ctxt);
                else
                    ret = udt;
            }
            else if (m is IAbstractSyntaxTree)
            {
                var mod = (IAbstractSyntaxTree)m;
                if (typeBase != null && typeBase.ToString() != mod.ModuleName)
                {
                    var pack = ctxt.ParseCache.LookupPackage(typeBase.ToString()).First();
                    if (pack != null)
                        ret = new PackageSymbol(pack, typeBase as ISyntaxRegion);
                }
                else
                    ret = new ModuleSymbol(m as DModule, typeBase as ISyntaxRegion);
            }
            else if (m is DEnum)
                ret = new EnumType((DEnum)m, typeBase as ISyntaxRegion);
            else if (m is TemplateParameterNode)
            {
                var tmp = ((TemplateParameterNode)m).TemplateParameter;

                //ResolveResult[] templateParameterType = null;

                //TODO: Resolve the specialization type
                //var templateParameterType = TemplateInstanceHandler.ResolveTypeSpecialization(tmp, ctxt);

                ret = new MemberSymbol((DNode)m, null, typeBase as ISyntaxRegion);
            }

            if (canResolveBaseGenerally && resultBase is DSymbol)
                ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals((DSymbol)resultBase);

            if (popAfterwards)
                ctxt.Pop();

            stackNum_HandleNodeMatch--;
            return ret;
        }
Exemple #23
0
 public AssocArrayPointer(MemberSymbol assocArrayVariable, ISymbolValue accessedItemKey)
     : base(assocArrayVariable)
 {
     Key = accessedItemKey;
 }
        private static void GenerateInlineScriptExpression(ScriptGenerator generator, MemberSymbol symbol, InlineScriptExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            string script = expression.Script;
            ICollection <Expression> parameters = expression.Parameters;

            if (parameters != null)
            {
                Debug.Assert(parameters.Count != 0);

                string[] parameterScripts = new string[parameters.Count];
                int      i = 0;

                foreach (Expression parameterExpression in parameters)
                {
                    StringWriter sw = new StringWriter();

                    try {
                        writer.StartLocalWriting(sw);
                        ExpressionGenerator.GenerateExpression(generator, symbol, parameterExpression);

                        parameterScripts[i] = sw.ToString();
                        i++;
                    }
                    finally {
                        writer.StopLocalWriting();
                    }
                }

                script = String.Format(CultureInfo.InvariantCulture, script, parameterScripts);
            }

            writer.Write(script);
        }
Exemple #25
0
 public StaticVariableValue(MemberSymbol staticPropertyResult)
     : base(staticPropertyResult)
 {
 }
        private static void GenerateLocalExpression(ScriptGenerator generator, MemberSymbol symbol, LocalExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            writer.Write(expression.Symbol.GeneratedName);
        }
Exemple #27
0
 public ArrayPointer(MemberSymbol arrayVariable, int accessedItem)
     : base(arrayVariable)
 {
     ItemNumber = accessedItem;
 }
        private static void GenerateNewExpression(ScriptGenerator generator, MemberSymbol symbol, NewExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            if (expression.IsSpecificType)
            {
                string type = expression.AssociatedType.FullGeneratedName;
                if (type.Equals("Array"))
                {
                    if (expression.Parameters == null)
                    {
                        writer.Write("[]");
                    }
                    else if ((expression.Parameters.Count == 1) &&
                             (expression.Parameters[0].EvaluatedType == symbol.SymbolSet.ResolveIntrinsicType(IntrinsicType.Integer)))
                    {
                        writer.Write("new Array(");
                        GenerateExpression(generator, symbol, expression.Parameters[0]);
                        writer.Write(")");
                    }
                    else
                    {
                        writer.Write("[");
                        GenerateExpressionList(generator, symbol, expression.Parameters);
                        writer.Write("]");
                    }
                    return;
                }
                else if (type.Equals("Object"))
                {
                    if (expression.Parameters == null)
                    {
                        writer.Write("{}");
                    }
                    else
                    {
                        writer.Write("{ ");
                        GenerateExpressionListAsNameValuePairs(generator, symbol, expression.Parameters);
                        writer.Write(" }");
                    }
                    return;
                }
                else if (type.Equals("Tuple"))
                {
                    if ((expression.Parameters == null) || (expression.Parameters.Count == 0))
                    {
                        writer.Write("{ }");
                    }
                    else
                    {
                        writer.Write("{ ");
                        for (int i = 0; i < expression.Parameters.Count; i++)
                        {
                            if (i != 0)
                            {
                                writer.Write(", ");
                            }

                            writer.Write("item");
                            writer.Write(i + 1);
                            writer.Write(": ");
                            GenerateExpression(generator, symbol, expression.Parameters[i]);
                        }
                        writer.Write(" }");
                    }

                    return;
                }
                else if (expression.AssociatedType.Type == SymbolType.Record)
                {
                    if (expression.AssociatedType.IsApplicationType &&
                        ((RecordSymbol)expression.AssociatedType).Constructor == null)
                    {
                        writer.Write("{ }");
                        return;
                    }

                    writer.Write(expression.AssociatedType.FullGeneratedName);
                    writer.Write("(");
                    if (expression.Parameters != null)
                    {
                        GenerateExpressionList(generator, symbol, expression.Parameters);
                    }
                    writer.Write(")");

                    return;
                }
            }

            writer.Write("new ");
            if (expression.IsSpecificType)
            {
                writer.Write(expression.AssociatedType.FullGeneratedName);
            }
            else
            {
                GenerateExpression(generator, symbol, expression.TypeExpression);
            }
            writer.Write("(");
            if (expression.Parameters != null)
            {
                GenerateExpressionList(generator, symbol, expression.Parameters);
            }
            writer.Write(")");
        }
Exemple #29
0
 public VariableValue(MemberSymbol mr) : base(mr.Base)
 {
     this.Member   = mr;
     this.Variable = mr.Definition as DVariable;
 }
Exemple #30
0
 public VariableValue(MemberSymbol mr)
     : base(mr.Base)
 {
     this.Member = mr;
     this.Variable = mr.Definition as DVariable;
 }
        public static ISymbolValue Execute(MemberSymbol method, Dictionary<DVariable, ISymbolValue> arguments, AbstractSymbolValueProvider vp)
        {
            var dm = method.Definition as DMethod;
            var eval = new FunctionEvaluation(method,vp,arguments);

            var ctxt = vp.ResolutionContext;
            ctxt.PushNewScope(dm, dm.Body);

            try
            {
                dm.Body.Accept(eval);
            }
            catch (CtfeException ex)
            {
                vp.LogError(dm, "Can't execute function at precompile time: " + ex.Message);
            }

            var ret = Evaluation.GetVariableContents(eval.returnedValue, eval.vp);

            ctxt.Pop();

            return ret;

            //return new ErrorValue(new EvaluationException("CTFE is not implemented yet."));
        }
Exemple #32
0
 public AssocArrayPointer(MemberSymbol assocArrayVariable, ISymbolValue accessedItemKey)
     : base(assocArrayVariable)
 {
     Key = accessedItemKey;
 }
Exemple #33
0
 public ArrayPointer(MemberSymbol arrayVariable, int accessedItem)
     : base(arrayVariable)
 {
     ItemNumber = accessedItem;
 }
Exemple #34
0
 public StaticVariableValue(MemberSymbol staticPropertyResult)
     : base(staticPropertyResult)
 {
 }
Exemple #35
0
        void HandleMethod(DMethod dm, MemberSymbol alreadyResolvedMethod = null)
        {
            if (dm != null && dm.Parameters.Count > 0 && dm.Parameters[0].Type != null)
            {
                var pop = ctxt.ScopedBlock != dm;
                if (pop)
                    ctxt.PushNewScope (dm);

                var t = TypeDeclarationResolver.ResolveSingle (dm.Parameters [0].Type, ctxt);
                if (ResultComparer.IsImplicitlyConvertible (firstArgument, t, ctxt)) {
                    var res = alreadyResolvedMethod ?? new MemberSymbol (dm, null, sr);
                    res.Tag = new UfcsTag{ firstArgument=firstArgument };
                    matches.Add (res);
                }

                if (pop)
                    ctxt.Pop ();
            }
        }
        public AbstractType Visit(NewExpression nex)
        {
            // http://www.d-programming-language.org/expression.html#NewExpression
            AbstractType[] possibleTypes;

            if (nex.Type is IdentifierDeclaration)
            {
                possibleTypes = TypeDeclarationResolver.Resolve((IdentifierDeclaration)nex.Type, ctxt, filterForTemplateArgs: false);
            }
            else
            {
                possibleTypes = TypeDeclarationResolver.Resolve(nex.Type, ctxt);
            }

            var ctors = new Dictionary <DMethod, TemplateIntermediateType>();

            if (possibleTypes == null)
            {
                return(null);
            }

            foreach (var t in possibleTypes)
            {
                var ct = t as TemplateIntermediateType;
                if (ct != null &&
                    !ct.Definition.ContainsAttribute(DTokens.Abstract))
                {
                    foreach (var ctor in GetConstructors(ct))
                    {
                        // Omit all ctors that won't return the adequate
                        if (ct.Modifier != 0)
                        {
                            if (!ctor.ContainsAttribute(ct.Modifier, DTokens.Pure))
                            {
                                continue;
                            }
                        }
                        else if (ctor.Attributes != null && ctor.Attributes.Count != 0)
                        {
                            bool skip = false;
                            foreach (var attr in ctor.Attributes)
                            {
                                var mod = attr as Modifier;
                                if (mod != null)
                                {
                                    switch (mod.Token)
                                    {
                                    case DTokens.Const:
                                    case DTokens.Immutable:
                                    case DTokens.Shared:
                                    case DTokens.Nothrow:                                             // ?
                                        // not DTokens.Pure due to some mystical reasons
                                        skip = true;
                                        break;
                                    }

                                    if (skip)
                                    {
                                        break;
                                    }
                                }
                            }
                            if (skip)
                            {
                                continue;
                            }
                        }
                        ctors.Add(ctor, ct);
                    }
                }
                else if (t is AssocArrayType)
                {
                    t.NonStaticAccess = true;
                    return(AmbiguousType.Get(possibleTypes));
                }
            }

            if (ctors.Count == 0)
            {
                return(new UnknownType(nex));
            }

            // HACK: Return the base types immediately
            if (TryReturnMethodReturnType)
            {
                var ret = ctors.First().Value;                 // AmbiguousType.Get(ctors.Values);
                if (ret != null)
                {
                    ret.NonStaticAccess = true;
                }
                return(ret);
            }

            MemberSymbol finalCtor = null;

            //TODO: Determine argument types and filter out ctor overloads.
            var kvFirst = ctors.First();

            finalCtor = new MemberSymbol(kvFirst.Key, kvFirst.Value, nex);



            if (finalCtor != null)
            {
                return(TryPretendMethodExecution(finalCtor, nex));
            }

            var resolvedCtors = new List <AbstractType>();

            foreach (var kv in ctors)
            {
                resolvedCtors.Add(new MemberSymbol(kv.Key, kv.Value, nex));
            }

            return(TryPretendMethodExecution(AmbiguousType.Get(resolvedCtors, nex), nex));
        }
        private static void GenerateThisExpression(ScriptGenerator generator, MemberSymbol symbol, ThisExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            writer.Write(generator.CurrentImplementation.ThisIdentifier);
        }
        private static void GenerateBinaryExpression(ScriptGenerator generator, MemberSymbol symbol,
                                                     BinaryExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            if (expression.Operator == Operator.Equals)
            {
                if (expression.LeftOperand is PropertyExpression propExpression)
                {
                    Debug.Assert(propExpression.Type == ExpressionType.PropertySet);

                    if (propExpression.ObjectReference is BaseExpression)
                    {
                        ClassSymbol classSymbol = (ClassSymbol)symbol.Parent;
                        writer.Write($"{DSharpStringResources.ScriptExportMember("baseProperty")}(");
                        writer.Write(classSymbol.FullGeneratedName);
                        writer.Write(", '");
                        writer.Write(propExpression.Property.GeneratedName);
                        writer.Write("').set.call(");
                        writer.Write(generator.CurrentImplementation.ThisIdentifier);
                        writer.Write(", ");
                        GenerateExpression(generator, symbol, expression.RightOperand);
                        writer.Write(")");
                    }
                    else
                    {
                        GenerateExpression(generator, symbol, propExpression.ObjectReference);
                        writer.Write(".");
                        writer.Write(propExpression.Property.GeneratedName);
                        writer.Write(" = ");
                        GenerateExpression(generator, symbol, expression.RightOperand);
                    }

                    propExpression.Property.IncrementReferenceCount();
                    return;
                }

                if (expression.LeftOperand is IndexerExpression indexExpression)
                {
                    IndexerSymbol indexerSymbol = indexExpression.Indexer;

                    if (!indexerSymbol.UseScriptIndexer)
                    {
                        Debug.Assert(indexExpression.Type == ExpressionType.Indexer);

                        if (indexExpression.ObjectReference is BaseExpression objectReference)
                        {
                            writer.Write(objectReference.EvaluatedType.FullGeneratedName);
                            writer.Write(".prototype.set_");
                            writer.Write(indexerSymbol.GeneratedName);
                            writer.Write(".call(");
                            writer.Write(generator.CurrentImplementation.ThisIdentifier);
                            writer.Write(", ");
                            GenerateExpressionList(generator, symbol, indexExpression.Indices);
                            writer.Write(", ");
                            GenerateExpression(generator, symbol, expression.RightOperand);
                            writer.Write(")");
                        }
                        else
                        {
                            GenerateExpression(generator, symbol, indexExpression.ObjectReference);
                            writer.Write(".set_");
                            writer.Write(indexerSymbol.GeneratedName);
                            writer.Write("(");
                            GenerateExpressionList(generator, symbol, indexExpression.Indices);
                            writer.Write(", ");
                            GenerateExpression(generator, symbol, expression.RightOperand);
                            writer.Write(")");
                        }

                        indexExpression.Indexer.IncrementReferenceCount();
                        return;
                    }
                    else if (indexerSymbol.Parent is TypeSymbol typeSymbol && !typeSymbol.IsNativeArray)
                    {
                        writer.Write($"ss.setItem(");
                        GenerateExpression(generator, symbol, indexExpression.ObjectReference);
                        writer.Write(", ");
                        GenerateExpressionList(generator, symbol, indexExpression.Indices);
                        writer.Write(", ");
                        GenerateExpression(generator, symbol, expression.RightOperand);
                        writer.Write(")");

                        return;
                    }
                }
            }
            else if (expression.Operator == Operator.PlusEquals ||
                     expression.Operator == Operator.MinusEquals ||
                     expression.Operator == Operator.MultiplyEquals ||
                     expression.Operator == Operator.DivideEquals ||
                     expression.Operator == Operator.ModEquals ||
                     expression.Operator == Operator.BitwiseOrEquals ||
                     expression.Operator == Operator.BitwiseAndEquals ||
                     expression.Operator == Operator.BitwiseXorEquals ||
                     expression.Operator == Operator.ShiftLeftEquals ||
                     expression.Operator == Operator.ShiftRightEquals ||
                     expression.Operator == Operator.UnsignedShiftRightEquals)
            {
                if (expression.LeftOperand is PropertyExpression propExpression)
                {
                    Debug.Assert(propExpression.Type == ExpressionType.PropertyGet);

                    GenerateExpression(generator, symbol, propExpression.ObjectReference);
                    writer.Write(".");
                    writer.Write(propExpression.Property.GeneratedName);
                    writer.Write(" = ");
                    GenerateExpression(generator, symbol, propExpression.ObjectReference);
                    writer.Write(OperatorConverter.OperatorToString(expression.Operator - 1));
                    GenerateExpression(generator, symbol, expression.RightOperand);

                    propExpression.Property.IncrementReferenceCount();
                    return;
                }
            }
            else if (expression.Operator == Operator.Is ||
                     expression.Operator == Operator.As)
            {
                TypeExpression typeExpression = expression.RightOperand as TypeExpression;
                Debug.Assert(typeExpression != null);

                writer.Write(DSharpStringResources.ScriptExportMember(string.Empty));

                if (expression.Operator == Operator.Is)
                {
                    writer.Write("canCast(");
                }
                else
                {
                    writer.Write("safeCast(");
                }

                GenerateExpression(generator, symbol, expression.LeftOperand);

                writer.Write(", ");
                writer.Write(typeExpression.AssociatedType.FullGeneratedName);
                writer.Write(")");
                typeExpression.AssociatedType.IncrementReferenceCount();
                return;
            }
            else if (expression.Operator == Operator.EqualEqualEqual ||
                     expression.Operator == Operator.NotEqualEqual)
            {
                if (expression.RightOperand is LiteralExpression literalExpression)
                {
                    // Optimize generated script to perform loose equality checks for false-y values
                    // (null, false, 0, empty string)

                    // TODO: This should really be happening at compilation time, rather than generation
                    //       time. Because this is happening at generation time, we get something like
                    //       if (!!x) when if(x) would suffice just so we can get
                    //       foo(!!x) where foo is a method expecting a boolean.
                    //       Doing this at compilation time would allow handling if scenarios specially.

                    bool optimizable   = false;
                    bool checkForFalse = false;

                    if (literalExpression.Value is bool compareValue)
                    {
                        optimizable = true;

                        if (compareValue && expression.Operator == Operator.NotEqualEqual ||
                            !compareValue && expression.Operator == Operator.EqualEqualEqual)
                        {
                            checkForFalse = true;
                        }
                    }
                    else if (literalExpression.Value is int i && i == 0)
                    {
                        optimizable   = true;
                        checkForFalse = expression.Operator == Operator.EqualEqualEqual;
                    }
                    else if (literalExpression.Value is string s && s == string.Empty)
                    {
                        optimizable   = true;
                        checkForFalse = expression.Operator == Operator.EqualEqualEqual;
                    }

                    if (optimizable)
                    {
                        bool parenthesize = false;

                        writer.Write(checkForFalse ? "!" : "!!");

                        if (expression.LeftOperand.Parenthesized == false &&
                            (expression.LeftOperand.Type == ExpressionType.Binary ||
                             expression.LeftOperand.Type == ExpressionType.Conditional ||
                             expression.LeftOperand.Type == ExpressionType.InlineScript))
                        {
                            parenthesize = true;
                            writer.Write("(");
                        }

                        GenerateExpression(generator, symbol, expression.LeftOperand);

                        if (parenthesize)
                        {
                            writer.Write(")");
                        }

                        return;
                    }
                }
            }
        private static void GenerateTypeExpression(ScriptGenerator generator, MemberSymbol symbol, TypeExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            writer.Write(expression.AssociatedType.FullGeneratedName);
        }
Exemple #40
0
        private static void GenerateForInStatement(ScriptGenerator generator, MemberSymbol symbol,
                                                   ForInStatement statement)
        {
            ScriptTextWriter writer        = generator.Writer;
            TypeSymbol       evaluatedType = statement.CollectionExpression.EvaluatedType;

            if (statement.IsDictionaryEnumeration)
            {
                if (statement.DictionaryVariable != null)
                {
                    writer.Write("var ");
                    writer.Write(statement.DictionaryVariable.GeneratedName);
                    writer.Write(" = ");
                    ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                    writer.Write(";");
                    writer.WriteLine();
                }

                writer.Write("for (var ");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.Write(" in ");

                if (statement.DictionaryVariable != null)
                {
                    writer.Write(statement.DictionaryVariable.GeneratedName);
                }
                else
                {
                    ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                }

                writer.WriteLine(") {");
                writer.Indent++;
                writer.Write("var ");
                writer.Write(statement.ItemVariable.GeneratedName);
                writer.Write(" = { key: ");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.Write(", value: ");

                if (statement.DictionaryVariable != null)
                {
                    writer.Write(statement.DictionaryVariable.GeneratedName);
                }
                else
                {
                    ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                }

                writer.Write("[");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.WriteLine("] };");
                GenerateStatement(generator, symbol, statement.Body);
                writer.Indent--;
                writer.WriteLine("}");
            }
            else if (evaluatedType.IsNativeArray || evaluatedType.IsListType())
            {
                string dataSourceVariableName = statement.LoopVariable.GeneratedName;
                string indexVariableName      = dataSourceVariableName + "_index";

                // var $$ = ({CollectionExpression});
                writer.Write("var " + dataSourceVariableName + " = (");
                ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                writer.WriteLine(");");

                // for(var items_index = 0; items_index < items.length; ++items_index) {
                writer.WriteLine("for(var " + indexVariableName + " = 0; " + indexVariableName + " < " + dataSourceVariableName + ".length; ++" + indexVariableName + ") {");

                ++writer.Indent;

                if (evaluatedType.IsNativeArray)
                {
                    // var i = items[items_index];
                    writer.WriteLine("var " + statement.ItemVariable.GeneratedName + " = " + dataSourceVariableName + "[" + indexVariableName + "];");
                }
                else
                {
                    // var i = ss.getItem(items, items_index);
                    writer.WriteLine("var " + statement.ItemVariable.GeneratedName + " = ss.getItem(" + dataSourceVariableName + ", " + indexVariableName + ");");
                }

                GenerateStatement(generator, symbol, statement.Body);

                --writer.Indent;
                writer.WriteLine("}");
            }
            else
            {
                writer.Write("var ");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.Write(" = ");

                writer.Write($"{DSharpStringResources.ScriptExportMember("enumerate")}(");
                ExpressionGenerator.GenerateExpression(generator, symbol, statement.CollectionExpression);
                writer.Write(");");

                writer.WriteLine();

                writer.Write("while (");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.WriteLine(".moveNext()) {");
                writer.Indent++;

                writer.Write("var ");
                writer.Write(statement.ItemVariable.GeneratedName);
                writer.Write(" = ");
                writer.Write(statement.LoopVariable.GeneratedName);
                writer.Write(".current;");
                writer.WriteLine();

                GenerateStatement(generator, symbol, statement.Body);

                writer.Indent--;
                writer.Write("}");
                writer.WriteLine();
            }
        }
        private static void GenerateBaseInitializerExpression(ScriptGenerator generator, MemberSymbol symbol, BaseInitializerExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            Debug.Assert(symbol.Parent is ClassSymbol);

            ClassSymbol baseClass = ((ClassSymbol)symbol.Parent).BaseClass;

            Debug.Assert(baseClass != null);

            writer.Write(baseClass.FullGeneratedName);
            writer.Write(".call(this");
            if (expression.Parameters != null)
            {
                writer.Write(", ");
                GenerateExpressionList(generator, symbol, expression.Parameters);
            }
            writer.Write(")");
        }
Exemple #42
0
        private static void GenerateTryCatchFinallyStatement(ScriptGenerator generator, MemberSymbol symbol,
                                                             TryCatchFinallyStatement statement)
        {
            ScriptTextWriter writer = generator.Writer;

            writer.WriteLine("try {");
            writer.Indent++;
            GenerateStatement(generator, symbol, statement.Body);
            writer.Indent--;
            writer.WriteLine("}");

            if (statement.Catch != null)
            {
                writer.Write("catch (");
                writer.Write(statement.ExceptionVariable.GeneratedName);
                writer.WriteLine(") {");
                writer.Indent++;
                GenerateStatement(generator, symbol, statement.Catch);
                writer.Indent--;
                writer.WriteLine("}");
            }

            if (statement.Finally != null)
            {
                writer.WriteLine("finally {");
                writer.Indent++;
                GenerateStatement(generator, symbol, statement.Finally);
                writer.Indent--;
                writer.WriteLine("}");
            }
        }
        private static void GenerateEnumerationFieldExpression(ScriptGenerator generator, MemberSymbol symbol, EnumerationFieldExpression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            ExpressionGenerator.GenerateExpression(generator, symbol, expression.ObjectReference);
            writer.Write(".");
            writer.Write(expression.Field.GeneratedName);
        }
 private bool MemberIsNotAliased(MemberSymbol arg)
 {
     return(!arg.GeneratedName.Contains('.'));
 }
        public static void GenerateExpression(ScriptGenerator generator, MemberSymbol symbol, Expression expression)
        {
            ScriptTextWriter writer = generator.Writer;

            if (expression.Parenthesized)
            {
                writer.Write("(");
            }

            switch (expression.Type)
            {
            case ExpressionType.Literal:
                GenerateLiteralExpression(generator, symbol, (LiteralExpression)expression);
                break;

            case ExpressionType.Local:
                GenerateLocalExpression(generator, symbol, (LocalExpression)expression);
                break;

            case ExpressionType.Member:
                Debug.Fail("MemberExpression missed from conversion to higher level expression.");
                break;

            case ExpressionType.Field:
                GenerateFieldExpression(generator, symbol, (FieldExpression)expression);
                break;

            case ExpressionType.EnumerationField:
                GenerateEnumerationFieldExpression(generator, symbol, (EnumerationFieldExpression)expression);
                break;

            case ExpressionType.PropertyGet:
                GeneratePropertyExpression(generator, symbol, (PropertyExpression)expression);
                break;

            case ExpressionType.PropertySet:
                Debug.Fail("PropertyExpression(set) should be covered as part of BinaryExpression logic.");
                break;

            case ExpressionType.MethodInvoke:
            case ExpressionType.DelegateInvoke:
                GenerateMethodExpression(generator, symbol, (MethodExpression)expression);
                break;

            case ExpressionType.BaseInitializer:
                GenerateBaseInitializerExpression(generator, symbol, (BaseInitializerExpression)expression);
                break;

            case ExpressionType.EventAdd:
            case ExpressionType.EventRemove:
                GenerateEventExpression(generator, symbol, (EventExpression)expression);
                break;

            case ExpressionType.Indexer:
                GenerateIndexerExpression(generator, symbol, (IndexerExpression)expression);
                break;

            case ExpressionType.This:
                GenerateThisExpression(generator, symbol, (ThisExpression)expression);
                break;

            case ExpressionType.Base:
                Debug.Fail("BaseExpression not handled by container expression.");
                break;

            case ExpressionType.New:
                GenerateNewExpression(generator, symbol, (NewExpression)expression);
                break;

            case ExpressionType.Unary:
                GenerateUnaryExpression(generator, symbol, (UnaryExpression)expression);
                break;

            case ExpressionType.Binary:
                GenerateBinaryExpression(generator, symbol, (BinaryExpression)expression);
                break;

            case ExpressionType.Conditional:
                GenerateConditionalExpression(generator, symbol, (ConditionalExpression)expression);
                break;

            case ExpressionType.Type:
                GenerateTypeExpression(generator, symbol, (TypeExpression)expression);
                break;

            case ExpressionType.Delegate:
                GenerateDelegateExpression(generator, symbol, (DelegateExpression)expression);
                break;

            case ExpressionType.LateBound:
                GenerateLateBoundExpression(generator, symbol, (LateBoundExpression)expression);
                break;

            case ExpressionType.InlineScript:
                GenerateInlineScriptExpression(generator, symbol, (InlineScriptExpression)expression);
                break;

            case ExpressionType.NewDelegate:
                GenerateExpression(generator, symbol, ((NewDelegateExpression)expression).TypeExpression);
                break;

            default:
                Debug.Fail("Unexpected expression type: " + expression.Type);
                break;
            }

            if (expression.Parenthesized)
            {
                writer.Write(")");
            }
        }