public override DVariable GetLocal(string LocalName, IdentifierExpression id = null) { var res = TypeDeclarationResolver.ResolveIdentifier(LocalName, ResolutionContext, id); if (res == null || res.Length == 0) { return(null); } var r = res[0]; if (r is MemberSymbol) { var mr = (MemberSymbol)r; if (mr.Definition is DVariable) { return((DVariable)mr.Definition); } } if (ev != null) { ev.EvalError(id ?? new IdentifierExpression(LocalName), LocalName + " must represent a local variable or a parameter", res); } return(null); }
public ISymbolValue Visit(UnaryExpression_Type x) { var uat = x as UnaryExpression_Type; if (uat.Type == null) { return(null); } var types = TypeDeclarationResolver.Resolve(uat.Type, ctxt); ctxt.CheckForSingleResult(types, uat.Type); if (types != null && types.Length != 0) { // First off, try to resolve static properties var statProp = StaticProperties.TryEvalPropertyValue(ValueProvider, types[0], uat.AccessIdentifierHash); if (statProp != null) { return(statProp); } //TODO } return(null); }
public static AbstractType[] GetOverloads(IdentifierExpression id, ResolverContextStack ctxt) { var raw = TypeDeclarationResolver.ResolveIdentifier(id.Value as string, ctxt, id, id.ModuleScoped); var f = DResolver.FilterOutByResultPriority(ctxt, raw); return(f == null ? null : f.ToArray()); }
public static AbstractType[] GetOverloads(IdentifierExpression id, ResolutionContext ctxt, IEnumerable <AbstractType> resultBases = null, bool deduceParameters = true) { AbstractType[] res; if (resultBases == null) { res = TypeDeclarationResolver.ResolveIdentifier(id.ValueStringHash, ctxt, id, id.ModuleScoped); } else { res = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(id.ValueStringHash, resultBases, ctxt, id); } if (res == null) { return(null); } var f = DResolver.FilterOutByResultPriority(ctxt, res); if (f.Count == 0) { return(null); } return((ctxt.Options & ResolutionOptions.NoTemplateParameterDeduction) == 0 && deduceParameters? TemplateInstanceHandler.DeduceParamsAndFilterOverloads(f, null, false, ctxt) : f.ToArray()); }
public static AbstractType ScanForCFunction(ResolutionContext ctxt, string funcName, bool isCFunction = true) { var extC = new Modifier(DTokens.Extern, "C"); foreach (var pc in ctxt.ParseCache) { foreach (var mod in pc) { var nodes = mod[funcName]; if (nodes != null) { foreach (var n in nodes) { if (n is DMethod) { var dm = n as DMethod; if (!isCFunction || dm.ContainsAttribute(extC)) { return(TypeDeclarationResolver.HandleNodeMatch(n, ctxt)); } } } } } } return(null); }
public void TryPreResolveCommonTypes() { var obj = GetModule("object"); if (obj == null) { return; } ParseCacheView cache = null; foreach (var m in obj) { if (m.Name == "Object" && m is DClassLike) { ObjectClassResult = new ClassType(ObjectClass = (DClassLike)m, new IdentifierDeclaration("Object"), null); break; } else if (m.Name == "size_t") { if (cache == null) { cache = new ParseCacheView(new[] { this }); } //TODO: Do a version check, so that only on x64 dmd installations, size_t equals ulong. SizeT = TypeDeclarationResolver.HandleNodeMatch(m, ResolutionContext.Create(cache, null, obj)); } } }
DNode[] ResolveTemplateInstanceId(TemplateInstanceExpression tix) { /* * Again a very unclear/buggy situation: * When having a cascaded tix as parameter, it uses the left-most part (i.e. the inner most) of the typedeclaration construct. * * class C(A!X.SubClass, X) {} can be instantiated via C!(A!int), but not via C!(A!int.SubClass) - totally confusing * (dmd v2.060) */ if (tix.InnerDeclaration != null) { if (tix.InnerMost is TemplateInstanceExpression) { tix = (TemplateInstanceExpression)tix.InnerMost; } else { return(new DNode[0]); } } var optBackup = ctxt.CurrentContext.ContextDependentOptions; ctxt.CurrentContext.ContextDependentOptions = ResolutionOptions.DontResolveBaseClasses | ResolutionOptions.DontResolveBaseTypes | ResolutionOptions.StopAfterFirstOverloads; var initialResults = TypeDeclarationResolver.ResolveIdentifier(tix.TemplateIdentifier.Id, ctxt, tix); var l = _handleResStep(initialResults); ctxt.CurrentContext.ContextDependentOptions = optBackup; return(l.ToArray()); }
List <DNode> _handleResStep(AbstractType[] res) { var l = new List <DNode>(); if (res != null) { foreach (var r in res) { if (r is AliasedType) { var alias = (AliasedType)r; AbstractType[] next = null; ctxt.CurrentContext.Set(alias.Definition.Parent as IBlockNode); if (alias.Definition.Type is IdentifierDeclaration) { next = TypeDeclarationResolver.Resolve((IdentifierDeclaration)alias.Definition.Type, ctxt, null, false); } else { next = TypeDeclarationResolver.Resolve(alias.Definition.Type, ctxt); } l.AddRange(_handleResStep(next)); } else if (r is DSymbol) { l.Add(((DSymbol)r).Definition); } } } return(l); }
public AbstractType Visit(UnaryExpression_Type x) { var uat = x as UnaryExpression_Type; if (uat.Type == null) { return(null); } var types = TypeDeclarationResolver.Resolve(uat.Type, ctxt); ctxt.CheckForSingleResult(types, uat.Type); if (types != null && types.Length != 0) { var res = TypeDeclarationResolver.Resolve(new IdentifierDeclaration(uat.AccessIdentifierHash) { EndLocation = uat.EndLocation }, ctxt, types); ctxt.CheckForSingleResult(res, x); if (res != null && res.Length != 0) { return(res[0]); } } return(null); }
bool HandleDecl(TemplateTypeParameter p, IdentifierDeclaration id, ISemantic r) { // Bottom-level reached if (id.InnerDeclaration == null && Contains(id.IdHash) && !id.ModuleScoped) { // Associate template param with r return(Set((p != null && id.IdHash == p.NameHash) ? p : null, r, id.IdHash)); } var deducee = DResolver.StripMemberSymbols(AbstractType.Get(r)) as DSymbol; if (id.InnerDeclaration != null && deducee != null && deducee.Definition.NameHash == id.IdHash) { var physicalParentType = TypeDeclarationResolver.HandleNodeMatch(deducee.Definition.Parent, ctxt, null, id.InnerDeclaration); if (HandleDecl(p, id.InnerDeclaration, physicalParentType)) { if (Contains(id.IdHash)) { Set((p != null && id.IdHash == p.NameHash) ? p : null, deducee, id.IdHash); } return(true); } } /* * If not stand-alone identifier or is not required as template param, resolve the id and compare it against r */ var _r = TypeDeclarationResolver.ResolveSingle(id, ctxt); return(_r != null && (EnforceTypeEqualityWhenDeducing ? ResultComparer.IsEqual(r, _r) : ResultComparer.IsImplicitlyConvertible(r, _r))); }
void parseThread(object pcl_shared) { DMethod dm = null; var pcl = (ParseCacheList)pcl_shared; var ctxt = new ResolverContextStack(pcl, new ResolverContext()); ctxt.ContextIndependentOptions |= ResolutionOptions.StopAfterFirstOverloads; while (queue.Count != 0) { lock (queue) { if (queue.Count == 0) { return; } dm = queue.Pop(); } ctxt.CurrentContext.ScopedBlock = dm; var firstArg_result = TypeDeclarationResolver.Resolve(dm.Parameters[0].Type, ctxt); if (firstArg_result != null && firstArg_result.Length != 0) { lock (CachedMethods) CachedMethods[dm] = firstArg_result[0]; } } }
public void CacheModuleMethods(IAbstractSyntaxTree ast, ResolverContextStack ctxt) { foreach (var m in ast) { if (m is DMethod) { var dm = (DMethod)m; if (dm.Parameters == null || dm.Parameters.Count == 0 || dm.Parameters[0].Type == null) { continue; } ctxt.PushNewScope(dm); var firstArg_result = TypeDeclarationResolver.Resolve(dm.Parameters[0].Type, ctxt); ctxt.Pop(); if (firstArg_result != null && firstArg_result.Length != 0) { lock (CachedMethods) CachedMethods[dm] = firstArg_result[0]; } } } }
public static StaticProperty TryEvalPropertyType(ResolutionContext ctxt, AbstractType t, int propName, bool staticOnly = false) { if (t is PointerType) { t = (t as PointerType).Base; } t = DResolver.StripMemberSymbols(t); if (t is PointerType) { t = (t as PointerType).Base; } if (t == null) { return(null); } var props = Properties[PropOwnerType.Generic]; StaticPropertyInfo prop; if (props.TryGetValue(propName, out prop) || (Properties.TryGetValue(GetOwnerType(t), out props) && props.TryGetValue(propName, out prop))) { var n = prop.GenerateRepresentativeNode(t); return(new StaticProperty(n, n.Type != null ? TypeDeclarationResolver.ResolveSingle(n.Type, ctxt) : null, prop.ValueGetter)); } return(null); }
public void IsExpressionAlias() { var ctxt = ResolutionTests.CreateCtxt("A", @"module A; static if(is(const(int)* U == const(U)*)) U var; U derp; "); IExpression x; AbstractType t; DSymbol ds; x = DParser.ParseExpression("var"); (x as IdentifierExpression).Location = new CodeLocation(2, 3); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); ds = t as DSymbol; Assert.That(t, Is.TypeOf(typeof(MemberSymbol))); Assert.That(ds.Base, Is.TypeOf(typeof(TemplateParameterSymbol))); ds = ds.Base as DSymbol; Assert.That(ds.Base, Is.TypeOf(typeof(PrimitiveType))); Assert.That((ds.Base as PrimitiveType).Modifier, Is.EqualTo(0)); ctxt.CurrentContext.DeducedTemplateParameters.Clear(); var dv = ctxt.ParseCache[0]["A"]["derp"].First() as DVariable; t = TypeDeclarationResolver.HandleNodeMatch(dv, ctxt); Assert.That(t, Is.TypeOf(typeof(MemberSymbol))); Assert.That((t as MemberSymbol).Base, Is.Null); }
void execTh(object p) { CanAbort = true; try { var tup = p as Tuple <ISyntaxRegion, ResolutionContext>; var sr = tup.Item1; var ctxt = tup.Item2; object result; VariableValue vv; if (sr is MixinStatement) { result = MixinAnalysis.ParseMixinDeclaration(sr as MixinStatement, ctxt, out vv); } else if (sr is TemplateMixin) { result = TypeDeclarationResolver.ResolveSingle((sr as TemplateMixin).Qualifier, ctxt); } else { result = null; } var o = ExpressionEvaluationPad.BuildObjectString(result); DispatchService.GuiDispatch(() => outputEditor.Text = o); } finally { CanAbort = false; } }
public static StaticProperty TryEvalPropertyType(ResolutionContext ctxt, AbstractType t, int propName, bool staticOnly = false) { GetLookedUpType(ref t); if (t == null) { return(null); } var props = Properties[PropOwnerType.Generic]; StaticPropertyInfo prop; if (props.TryGetValue(propName, out prop) || (Properties.TryGetValue(GetOwnerType(t), out props) && props.TryGetValue(propName, out prop))) { var n = prop.GenerateRepresentativeNode(t, ctxt); AbstractType baseType; if (prop.ResolvedBaseTypeGetter != null) { baseType = prop.ResolvedBaseTypeGetter(t, ctxt); } else if (n.Type != null) { baseType = TypeDeclarationResolver.ResolveSingle(n.Type, ctxt); } else { baseType = null; } return(new StaticProperty(n, baseType, prop.ValueGetter)); } return(null); }
/// <summary> /// http://dlang.org/expression.html#IsExpression /// </summary> public ISemantic E(IsExpression isExpression) { if (!eval) { return(new PrimitiveType(DTokens.Bool)); } bool retTrue = false; if (isExpression.TestedType != null) { var typeToCheck = DResolver.StripMemberSymbols(TypeDeclarationResolver.ResolveSingle(isExpression.TestedType, ctxt)); if (typeToCheck != null) { // case 1, 4 if (isExpression.TypeSpecialization == null && isExpression.TypeSpecializationToken == 0) { retTrue = true; } // The probably most frequented usage of this expression else if (isExpression.TypeAliasIdentifierHash == 0) { retTrue = evalIsExpression_NoAlias(isExpression, typeToCheck); } else { retTrue = evalIsExpression_WithAliases(isExpression, typeToCheck); } } } return(new PrimitiveValue(DTokens.Bool, retTrue?1:0, isExpression)); }
ISemantic E(CastExpression ce) { AbstractType castedType = null; if (ce.Type != null) { var castedTypes = TypeDeclarationResolver.Resolve(ce.Type, ctxt); ctxt.CheckForSingleResult(castedTypes, ce.Type); if (castedTypes != null && castedTypes.Length != 0) { castedType = castedTypes[0]; } } else { castedType = AbstractType.Get(E(ce.UnaryExpression)); if (castedType != null && ce.CastParamTokens != null && ce.CastParamTokens.Length > 0) { //TODO: Wrap resolved type with member function attributes } } return(castedType); }
protected override void BuildCompletionDataInternal(IEditorData Editor, char enteredChar) { ed = Editor; ctxt = ResolutionContext.Create(Editor, false); AbstractType t = null; CodeCompletion.DoTimeoutableCompletionTask(CompletionDataGenerator, ctxt, () => { ctxt.Push(Editor); if (AccessExpression is IExpression) { t = ExpressionTypeEvaluation.EvaluateType(AccessExpression as IExpression, ctxt); } else if (AccessExpression is ITypeDeclaration) { t = TypeDeclarationResolver.ResolveSingle(AccessExpression as ITypeDeclaration, ctxt); } }); if (t == null) //TODO: Add after-space list creation when an unbound . (Dot) was entered which means to access the global scope { return; } t.Accept(this); }
protected override void BuildCompletionDataInternal(IEditorData Editor, char enteredChar) { var ctxt = ResolutionContext.Create(Editor, true); var resolvedVariable = TypeDeclarationResolver.HandleNodeMatch(initedVar, ctxt) as DSymbol; if (resolvedVariable == null) { return; } while (resolvedVariable is TemplateParameterSymbol) { resolvedVariable = resolvedVariable.Base as DSymbol; } var structType = resolvedVariable.Base as TemplateIntermediateType; if (structType == null) { return; } var alreadyTakenNames = new List <int>(); foreach (var m in init.MemberInitializers) { alreadyTakenNames.Add(m.MemberNameHash); } new StructVis(structType, alreadyTakenNames, CompletionDataGenerator, ctxt); }
public ISymbolValue Visit(TypeDeclarationExpression x) { // should be containing a typeof() only; static properties etc. are parsed as access expressions var t = TypeDeclarationResolver.ResolveSingle(x.Declaration, ctxt); return(new TypeValue(t)); }
ISemantic E(TypeDeclarationExpression x) { if (eval) { throw new NotImplementedException("TODO: Handle static properties and ufcs functionality on type declaration expressions"); } return(TypeDeclarationResolver.ResolveSingle(((TypeDeclarationExpression)x).Declaration, ctxt)); }
bool Handle(TemplateValueParameter p, ISemantic arg) { // Handle default arg case if (arg == null) { if (p.DefaultExpression != null) { var eval = Evaluation.EvaluateValue(p.DefaultExpression, ctxt); if (eval == null) { return(false); } return(Set(p, eval)); } else { return(false); } } var valueArgument = arg as ISymbolValue; // There must be a constant expression given! if (valueArgument == null) { return(false); } // Check for param type <-> arg expression type match var paramType = TypeDeclarationResolver.Resolve(p.Type, ctxt); if (paramType == null || paramType.Length == 0) { return(false); } if (valueArgument.RepresentedType == null || !ResultComparer.IsImplicitlyConvertible(paramType[0], valueArgument.RepresentedType)) { return(false); } // If spec given, test for equality (only ?) if (p.SpecializationExpression != null) { var specVal = Evaluation.EvaluateValue(p.SpecializationExpression, ctxt); if (specVal == null || !SymbolValueComparer.IsEqual(specVal, valueArgument)) { return(false); } } return(Set(p, arg)); }
public AbstractType Visit(TypeidExpression x) { //TODO: Split up into more detailed typeinfo objects (e.g. for arrays, pointers, classes etc.) return(TypeDeclarationResolver.ResolveSingle(new IdentifierDeclaration("TypeInfo") { InnerDeclaration = new IdentifierDeclaration("object") }, ctxt)); }
public static AbstractType getStringType(ResolverContextStack ctxt) { var str = new IdentifierDeclaration("string"); var sType = TypeDeclarationResolver.Resolve(str, ctxt); ctxt.CheckForSingleResult(sType, str); return(sType != null && sType.Length != 0 ? sType[0] : null); }
void _th(object pcl_shared) { var pcl = (ParseCacheList)pcl_shared; var ctxt = new ResolverContextStack(pcl, new ResolverContext { ScopedBlock = ast }); // Make it as most performing as possible by avoiding unnecessary base types. // Aliases should be analyzed deeper though. ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.StopAfterFirstOverloads | ResolutionOptions.DontResolveBaseTypes | //TODO: Exactly find out which option can be enabled here. Resolving variables' types is needed sometimes - but only, when highlighting a variable reference is wanted explicitly. ResolutionOptions.NoTemplateParameterDeduction | ResolutionOptions.ReturnMethodReferencesOnly; ISyntaxRegion sr = null; int i = 0; while (curQueueOffset < queueCount) { // Avoid race condition runtime errors lock (_lockObject) { i = curQueueOffset; curQueueOffset++; } // Resolve gotten syntax object sr = q[i]; var sb = ctxt.CurrentContext.ScopedBlock; ctxt.CurrentContext.ScopedBlock = DResolver.SearchBlockAt( sb == null || sr.Location <sb.BlockStartLocation || sr.EndLocation> sb.EndLocation ? ast : sb, sr.Location, out ctxt.CurrentContext.ScopedStatement); if (sr is PostfixExpression_Access) { HandleAccessExpressions((PostfixExpression_Access)sr, ctxt); } else { AbstractType t = null; if (sr is IExpression) { t = DResolver.StripAliasSymbol(Evaluation.EvaluateType((IExpression)sr, ctxt)); } else if (sr is ITypeDeclaration) { t = DResolver.StripAliasSymbol(TypeDeclarationResolver.ResolveSingle((ITypeDeclaration)sr, ctxt)); } // Enter into the result list HandleResult(sr, t); } } }
ISemantic E(TypeDeclarationExpression x) { var t = TypeDeclarationResolver.ResolveSingle(x.Declaration, ctxt); if (eval) { return(new TypeValue(t)); } return(t); }
protected override bool HandleItem(INode n) { if (n != null && n.NameHash == filterHash) { matches_types.Add(TypeDeclarationResolver.HandleNodeMatch(n, ctxt, TemporaryResolvedNodeParent, idObject)); return(true); } return(false); }
private static void GetUnfilteredMethodOverloads_Helper(IExpression foreExpression, ResolutionContext ctxt, IExpression supExpression, List <AbstractType> l, ref bool staticOnly, AbstractType ov) { var t = ov; if (ov is MemberSymbol) { var ms = ov as MemberSymbol; if (ms.Definition is Dom.DMethod) { l.Add(ms); return; } staticOnly = false; t = ms.Base; } if (t is TemplateIntermediateType) { var tit = t as TemplateIntermediateType; var m = TypeDeclarationResolver.HandleNodeMatches( GetOpCalls(tit, staticOnly), ctxt, null, supExpression ?? foreExpression); /* * On structs, there must be a default () constructor all the time. * If there are (other) constructors in structs, the explicit member initializer constructor is not * provided anymore. This will be handled in the GetConstructors() method. * If there are opCall overloads, canCreateeExplicitStructCtor overrides the ctor existence check in GetConstructors() * and enforces that the explicit ctor will not be generated. * An opCall overload with no parameters supersedes the default ctor. */ var canCreateExplicitStructCtor = m == null || m.Length == 0; if (!canCreateExplicitStructCtor) { l.AddRange(m); } m = TypeDeclarationResolver.HandleNodeMatches( GetConstructors(tit, canCreateExplicitStructCtor), ctxt, null, supExpression ?? foreExpression); if (m != null && m.Length != 0) { l.AddRange(m); } } else { l.Add(ov); } }
public void IsExpressionAlias_InMethod() { var ctxt = ResolutionTests.CreateCtxt("A", @"module A; void main(){ pre; static if(is(const(int)* U == const(U)*)) { U var; } post; } "); IExpression x; AbstractType t; DSymbol ds; var main = ctxt.ParseCache[0]["A"]["main"].First() as DMethod; ctxt.PushNewScope(main, main.Body.SubStatements.First()); t = TypeDeclarationResolver.ResolveSingle(new IdentifierDeclaration("U") { Location = main.Body.SubStatements.First().Location }, ctxt); Assert.That(t, Is.Null); ctxt.Pop(); ctxt.PushNewScope(main, main.Body.SubStatements.ElementAt(2)); t = TypeDeclarationResolver.ResolveSingle(new IdentifierDeclaration("U") { Location = main.Body.SubStatements.ElementAt(2).Location }, ctxt); Assert.That(t, Is.Null); ctxt.Pop(); x = DParser.ParseExpression("var"); IStatement stmt; DResolver.SearchBlockAt(main, (x as IdentifierExpression).Location = new CodeLocation(3, 7), out stmt); ctxt.PushNewScope(main, stmt); t = ExpressionTypeEvaluation.EvaluateType(x, ctxt); ds = t as DSymbol; Assert.That(t, Is.TypeOf(typeof(MemberSymbol))); Assert.That(ds.Base, Is.TypeOf(typeof(TemplateParameterSymbol))); ds = ds.Base as DSymbol; Assert.That(ds.Base, Is.TypeOf(typeof(PrimitiveType))); Assert.That((ds.Base as PrimitiveType).Modifier, Is.EqualTo(0)); }