public void TestAccessExpression() { var pcl = ResolutionTests.CreateCache(@"module modA; class A { const int someProp=3; } A a;"); var vp = new StandardValueProvider(ResolutionContext.Create(pcl, null, pcl[0]["modA"])); /* * var v = E("a.someProp", vp); * Assert.IsInstanceOfType(v, typeof(PrimitiveValue)); * Assert.AreEqual(((PrimitiveValue)v).Value,3); */ var v = E("A.someProp", vp); Assert.IsInstanceOfType(typeof(VariableValue), v); var vv = vp[((VariableValue)v).Variable] as PrimitiveValue; Assert.AreEqual(3, vv.Value); }
public static List <ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolverContextStack ctxt) { // Resolve given argument expressions var templateArguments = new List <ISemantic>(); if (tix != null && tix.Arguments != null) { foreach (var arg in tix.Arguments) { if (arg is TypeDeclarationExpression) { var tde = (TypeDeclarationExpression)arg; var res = TypeDeclarationResolver.Resolve(tde.Declaration, ctxt); if (ctxt.CheckForSingleResult(res, tde.Declaration) || res != null) { var mr = res[0] as MemberSymbol; if (mr != null && mr.Definition is DVariable) { var dv = (DVariable)mr.Definition; if (dv.IsAlias || dv.Initializer == null) { templateArguments.Add(mr); continue; } ISemantic eval = null; try { eval = new StandardValueProvider(ctxt)[dv]; } catch (System.Exception ee) // Should be a non-const-expression error here only { ctxt.LogError(dv.Initializer, ee.Message); } templateArguments.Add(eval == null ? (ISemantic)mr : eval); } else { templateArguments.Add(res[0]); } } } else { templateArguments.Add(Evaluation.EvaluateValue(arg, ctxt)); } } } return(templateArguments); }
public void TestCastExpression1() { var ctxt = ResolutionTests.CreateCtxt("A", @"module A;"); var vp = new StandardValueProvider(ctxt); IExpression x; ISymbolValue v; x = DParser.ParseExpression("cast(ubyte)20"); v = Evaluation.EvaluateValue(x, vp); Assert.That(v, Is.TypeOf(typeof(PrimitiveValue))); Assert.That((v as PrimitiveValue).BaseTypeToken, Is.EqualTo(DTokens.Ubyte)); Assert.That((v as PrimitiveValue).Value, Is.EqualTo(20M)); }
public void TestArrays() { var vp = new StandardValueProvider(null); var v = E("[11,22,33,43][1]", vp); Assert.IsInstanceOfType(typeof(PrimitiveValue), v); Assert.AreEqual(((PrimitiveValue)v).Value, 22); v = E("[11,22,33,44,55,66,77,88,99,100][1..3]", vp); Assert.IsInstanceOfType(typeof(ArrayValue), v); var av = (ArrayValue)v; Assert.AreEqual(av.Elements.Length, 2); Assert.AreEqual((av.Elements[0] as PrimitiveValue).Value, 22); }
public void TestConstEval() { var pcl = ResolutionTests.CreateCache(@"module modA; const a= 234; enum b=123; const int c=125; enum int d=126; "); var vp = new StandardValueProvider(ResolutionContext.Create(pcl, null, pcl[0]["modA"])); var v = E("a", vp); Assert.IsInstanceOfType(typeof(VariableValue), v); var val = vp[((VariableValue)v).Variable]; Assert.IsInstanceOfType(typeof(PrimitiveValue), val); var pv = (PrimitiveValue)val; Assert.AreEqual(pv.Value, 234M); v = E("b", vp); val = vp[((VariableValue)v).Variable]; pv = (PrimitiveValue)val; Assert.AreEqual(pv.Value, 123M); v = E("c", vp); val = vp[((VariableValue)v).Variable]; pv = (PrimitiveValue)val; Assert.AreEqual(pv.Value, 125M); v = E("d", vp); val = vp[((VariableValue)v).Variable]; pv = (PrimitiveValue)val; Assert.AreEqual(pv.Value, 126M); pv = E("d + 4", vp) as PrimitiveValue; Assert.IsNotNull(pv); Assert.AreEqual(130M, pv.Value); pv = E("d + a", vp) as PrimitiveValue; Assert.IsNotNull(pv); Assert.AreEqual(360M, pv.Value); }
public void TestIsExpression() { var pcl = ResolutionTests.CreateCache(@"module modA; class A {} class B : A {} class C : A {} struct DynArg(int i) { static assert (i >= 0); alias i argNr; } template isDynArg(T) { static if (is(typeof(T.argNr))) { // must have the argNr field static if(is(T : DynArg!(T.argNr))) { // now check the exact type static const bool isDynArg = true; } else static const bool isDynArg = false; } else static const bool isDynArg = false; } "); var vp = new StandardValueProvider(ResolutionContext.Create(pcl, null, pcl[0]["modA"])); Assert.IsTrue(EvalIsExpression("char*[] T : U[], U : V*, V", vp)); Assert.IsTrue(EvalIsExpression("string T : U[], U : immutable(V), V : char", vp)); Assert.IsFalse(EvalIsExpression("int[10] X : X[Y], int Y : 5", vp)); Assert.IsTrue(EvalIsExpression("bool : bool", vp)); Assert.IsTrue(EvalIsExpression("bool == bool", vp)); Assert.IsTrue(EvalIsExpression("C : A", vp)); Assert.IsTrue(EvalIsExpression("C : C", vp)); Assert.IsFalse(EvalIsExpression("C == A", vp)); Assert.IsTrue(EvalIsExpression("immutable(char) == immutable", vp)); Assert.IsFalse(EvalIsExpression("string == immutable", vp)); Assert.IsTrue(EvalIsExpression("A == class", vp)); Assert.IsTrue(EvalIsExpression("typeof(A)", vp)); Assert.IsFalse(EvalIsExpression("typeof(D)", vp)); }
/// <summary> /// Associates the given arguments with the template parameters specified in the type/method declarations /// and filters out unmatching overloads. /// </summary> /// <param name="rawOverloadList">Can be either type results or method results</param> /// <param name="givenTemplateArguments">A list of already resolved arguments passed explicitly /// in the !(...) section of a template instantiation /// or call arguments given in the (...) appendix /// that follows a method identifier</param> /// <param name="isMethodCall">If true, arguments that exceed the expected parameter count will be ignored as far as all parameters could be satisfied.</param> /// <param name="ctxt"></param> /// <returns>A filtered list of overloads which mostly fit to the specified arguments. /// Usually contains only 1 element. /// The 'TemplateParameters' property of the results will be also filled for further usage regarding smart completion etc.</returns> public static AbstractType[] DeduceParamsAndFilterOverloads(IEnumerable <AbstractType> rawOverloadList, IEnumerable <ISemantic> givenTemplateArguments, bool isMethodCall, ResolutionContext ctxt, bool hasUndeterminedArguments = false) { if (rawOverloadList == null) { return(null); } var filteredOverloads = hasUndeterminedArguments ? new List <AbstractType>(rawOverloadList) : DeduceOverloads(rawOverloadList, givenTemplateArguments, isMethodCall, ctxt); AbstractType[] sortedAndFilteredOverloads; // If there are >1 overloads, filter from most to least specialized template param if (filteredOverloads.Count > 1) { sortedAndFilteredOverloads = SpecializationOrdering.FilterFromMostToLeastSpecialized(filteredOverloads, ctxt); } else if (filteredOverloads.Count == 1) { sortedAndFilteredOverloads = new[] { filteredOverloads[0] } } ; else { return(null); } if (hasUndeterminedArguments) { return(sortedAndFilteredOverloads); } if (sortedAndFilteredOverloads != null) { filteredOverloads.Clear(); for (int i = sortedAndFilteredOverloads.Length - 1; i >= 0; i--) { var ds = sortedAndFilteredOverloads[i] as DSymbol; if (ds != null && ds.Definition.TemplateConstraint != null) { ctxt.CurrentContext.IntroduceTemplateParameterTypes(ds); try{ var v = Evaluation.EvaluateValue(ds.Definition.TemplateConstraint, ctxt); if (v is VariableValue) { v = new StandardValueProvider(ctxt)[((VariableValue)v).Variable]; } if (!Evaluation.IsFalseZeroOrNull(v)) { filteredOverloads.Add(ds); } }catch {} //TODO: Handle eval exceptions ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ds); } else { filteredOverloads.Add(sortedAndFilteredOverloads[i]); } } if (filteredOverloads.Count == 0) { return(null); } sortedAndFilteredOverloads = filteredOverloads.ToArray(); } if (sortedAndFilteredOverloads != null && sortedAndFilteredOverloads.Length == 1) { var t = sortedAndFilteredOverloads [0]; if (t is TemplateType) { return(TryGetImplicitProperty(t as TemplateType, ctxt) ?? sortedAndFilteredOverloads); } if (t is EponymousTemplateType) { return new[] { DeduceEponymousTemplate(t as EponymousTemplateType, ctxt) } } ; } return(sortedAndFilteredOverloads); }
public static List <ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolutionContext ctxt, out bool hasNonFinalArgument) { hasNonFinalArgument = false; // Resolve given argument expressions var templateArguments = new List <ISemantic>(); if (tix != null && tix.Arguments != null) { foreach (var arg in tix.Arguments) { if (arg is TypeDeclarationExpression) { var tde = (TypeDeclarationExpression)arg; var res = TypeDeclarationResolver.Resolve(tde.Declaration, ctxt); // Might be a simple symbol without any applied template arguments that is then passed to an template alias parameter if (res == null && tde.Declaration is IdentifierDeclaration) { res = TypeDeclarationResolver.Resolve(tde.Declaration as IdentifierDeclaration, ctxt, null, false); } if (ctxt.CheckForSingleResult(res, tde.Declaration) || (res != null && res.Length > 0)) { var mr = res[0] as MemberSymbol; if (mr != null && mr.Definition is DVariable) { var dv = (DVariable)mr.Definition; if (dv.IsAlias || dv.Initializer == null) { templateArguments.Add(mr); continue; } ISemantic eval = null; try { eval = new StandardValueProvider(ctxt)[dv]; } catch (System.Exception ee) // Should be a non-const-expression error here only { ctxt.LogError(dv.Initializer, ee.Message); } templateArguments.Add(eval ?? (ISemantic)mr); } else { if (!hasNonFinalArgument) { hasNonFinalArgument = IsNonFinalArgument(res[0]); } templateArguments.Add(res[0]); } } } else { ISemantic v = Evaluation.EvaluateValue(arg, ctxt, true); if (v is VariableValue) { var vv = v as VariableValue; if (vv.Variable.IsConst && vv.Variable.Initializer != null) { v = Evaluation.EvaluateValue(vv, new StandardValueProvider(ctxt)); } } if (!hasNonFinalArgument) { hasNonFinalArgument = IsNonFinalArgument(v); } v = DResolver.StripValueTypeWrappers(v); templateArguments.Add(v); } } } return(templateArguments); }