public ArgumentsInfo(IEmitter emitter, AssignmentExpression assignmentExpression, OperatorResolveResult operatorResolveResult, IMethod method) { this.Emitter = emitter; this.Expression = assignmentExpression; this.OperatorResolveResult = operatorResolveResult; this.BuildOperatorArgumentsList(new Expression[] { assignmentExpression.Left, assignmentExpression.Right }, operatorResolveResult.UserDefinedOperatorMethod ?? method); this.BuildOperatorTypedArguments(); }
private JsNode Trinary(OperatorResolveResult res) { if (res.OperatorType == ExpressionType.Conditional) { var node5 = new JsConditionalExpression { Condition = VisitExpression(res.Operands[0]), TrueExpression = VisitExpression(res.Operands[1]), FalseExpression = VisitExpression(res.Operands[2]) }; return node5; } else throw new NotImplementedException(); }
/// <summary> /// https://github.com/icsharpcode/NRefactory/issues/501 /// </summary> OperatorResolveResult WorkaroundIssue501(OperatorResolveResult res) { if (res.UserDefinedOperatorMethod == null) return res; if ((res.OperatorType == ExpressionType.AndAlso && res.UserDefinedOperatorMethod.Name == "op_BitwiseAnd") || (res.OperatorType == ExpressionType.OrElse && res.UserDefinedOperatorMethod.Name == "op_BitwiseOr")) { var fake = new OperatorResolveResult(res.Type, res.OperatorType, null, res.IsLiftedOperator, res.Operands); return fake; } return res; }
protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr) { var method = orr != null ? orr.UserDefinedOperatorMethod : null; if (method != null) { var inline = this.Emitter.GetInline(method); if (!string.IsNullOrWhiteSpace(inline)) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit(); return true; } else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition)) { if (orr.IsLiftedOperator) { this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable.lift("); } this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(OverloadsCollection.Create(this.Emitter, method).GetOverloadName()); if (orr.IsLiftedOperator) { this.WriteComma(); } else { this.WriteOpenParentheses(); } new ExpressionListBlock(this.Emitter, new Expression[] {binaryOperatorExpression.Left, binaryOperatorExpression.Right}, null).Emit(); this.WriteCloseParentheses(); return true; } } return false; }
public ArgumentsInfo(IEmitter emitter, BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult operatorResolveResult) { this.Emitter = emitter; this.Expression = binaryOperatorExpression; this.OperatorResolveResult = operatorResolveResult; if (operatorResolveResult.UserDefinedOperatorMethod != null) { this.BuildOperatorArgumentsList(new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right }); this.BuildOperatorTypedArguments(); } else { this.ArgumentsExpressions = new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right }; this.ArgumentsNames = new string[] { "left", "right" }; this.CreateNamedExpressions(this.ArgumentsNames, this.ArgumentsExpressions); } }
public JsNode VisitOperatorResolveResult(OperatorResolveResult res) { if (res.Operands.Count == 1) return Unary(res); else if (res.Operands.Count == 2) { var node2 = Binary(res); if (Importer.ForceIntegers) { if (Importer.IsInteger(res.Type) && res.OperatorType == ExpressionType.Divide) node2 = Importer.ForceInteger(node2); } return node2; } else if (res.Operands.Count == 3) return Trinary(res); else throw new NotImplementedException(); }
protected bool IsUserOperator(OperatorResolveResult orr) { var method = orr != null ? orr.UserDefinedOperatorMethod : null; if (method != null) { var inline = this.Emitter.GetInline(method); if (!string.IsNullOrWhiteSpace(inline)) { return true; } else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition)) { return true; } } return false; }
string Visit(OperatorResolveResult result) { throw new NotImplementedException(); }
Value VisitConditionalOperator(OperatorResolveResult result, BinaryOperatorType bitwiseOperatorType) { Debug.Assert(result.Operands.Count == 2); var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread); CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem); Value condVal; if (bitwiseOperatorType == BinaryOperatorType.BitwiseAnd) condVal = Convert(resolver.ResolveConditionFalse(lhs.ToResolveResult(context))); else condVal = Convert(resolver.ResolveCondition(lhs.ToResolveResult(context))); if ((bool)condVal.PrimitiveValue) return lhs; var rhs = Convert(result.Operands[1]); var val = resolver.ResolveBinaryOperator(bitwiseOperatorType, lhs.ToResolveResult(context), rhs.ToResolveResult(context)); return Convert(val); }
Value VisitBinaryOperator(OperatorResolveResult result, BinaryOperatorType operatorType, bool checkForOverflow = false) { Debug.Assert(result.Operands.Count == 2); Debug.Assert(operatorType != BinaryOperatorType.ConditionalAnd && operatorType != BinaryOperatorType.ConditionalOr && operatorType != BinaryOperatorType.NullCoalescing); var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread); var rhs = Convert(result.Operands[1]).GetPermanentReference(evalThread); if (result.UserDefinedOperatorMethod != null) return InvokeMethod(null, result.UserDefinedOperatorMethod, lhs, rhs); var lhsRR = lhs.ToResolveResult(context); var rhsRR = rhs.ToResolveResult(context); CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow); var val = resolver.ResolveBinaryOperator(operatorType, lhsRR, rhsRR); if (val.IsCompileTimeConstant) return Convert(val); switch (operatorType) { case BinaryOperatorType.Equality: case BinaryOperatorType.InEquality: bool equality = (operatorType == BinaryOperatorType.Equality); if (lhsRR.Type.IsKnownType(KnownTypeCode.String) && rhsRR.Type.IsKnownType(KnownTypeCode.String)) { if (lhs.IsNull || rhs.IsNull) { bool bothNull = lhs.IsNull && rhs.IsNull; return Eval.CreateValue(evalThread, equality ? bothNull : !bothNull); } else { bool equal = (string)lhs.PrimitiveValue == (string)rhs.PrimitiveValue; return Eval.CreateValue(evalThread, equality ? equal : !equal); } } if (lhsRR.Type.IsReferenceType != false && rhsRR.Type.IsReferenceType != false) { // Reference comparison if (lhs.IsNull || rhs.IsNull) { bool bothNull = lhs.IsNull && rhs.IsNull; return Eval.CreateValue(evalThread, equality ? bothNull : !bothNull); } else { bool equal = lhs.Address == rhs.Address; return Eval.CreateValue(evalThread, equality ? equal : !equal); } } goto default; case BinaryOperatorType.Add: if (lhsRR.Type.IsKnownType(KnownTypeCode.String) || rhsRR.Type.IsKnownType(KnownTypeCode.String)) { var method = debuggerTypeSystem.FindType(KnownTypeCode.String) .GetMethods(m => m.Name == "Concat" && m.Parameters.Count == 2) .Single(m => m.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Object))); return InvokeMethod(null, method, lhs, rhs); } goto default; default: throw new GetValueException("Operator {0} is not supported for {1} and {2}!", operatorType, new CSharpAmbience().ConvertType(lhsRR.Type), new CSharpAmbience().ConvertType(rhsRR.Type)); } }
Value VisitUnaryOperator(OperatorResolveResult result, UnaryOperatorType operatorType, bool checkForOverflow = false) { Debug.Assert(result.Operands.Count == 1); var operand = Convert(result.Operands[0]).ToResolveResult(context); CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow); var val = resolver.ResolveUnaryOperator(operatorType, operand); if (val.IsCompileTimeConstant) return Convert(val); throw new GetValueException("Operator {0} is not supported for {1}!", operatorType, new CSharpAmbience().ConvertType(operand.Type)); }
Value VisitTernaryOperator(OperatorResolveResult result) { Debug.Assert(result.Operands.Count == 3); var condition = Convert(result.Operands[0]); if (!condition.Type.IsKnownType(KnownTypeCode.Boolean)) throw new GetValueException("Boolean expression expected!"); if ((bool)condition.PrimitiveValue) return Convert(result.Operands[1]); return Convert(result.Operands[2]); }
Value Visit(OperatorResolveResult result) { switch (result.OperatorType) { case ExpressionType.Assign: if (!allowSetValue) throw new GetValueException("Setting values is not allowed in the current context!"); Debug.Assert(result.Operands.Count == 2); return VisitAssignment((dynamic)result.Operands[0], (dynamic)result.Operands[1]); case ExpressionType.Add: return VisitBinaryOperator(result, BinaryOperatorType.Add, false); case ExpressionType.AddChecked: return VisitBinaryOperator(result, BinaryOperatorType.Add, true); case ExpressionType.Subtract: return VisitBinaryOperator(result, BinaryOperatorType.Subtract, false); case ExpressionType.SubtractChecked: return VisitBinaryOperator(result, BinaryOperatorType.Subtract, true); case ExpressionType.Multiply: return VisitBinaryOperator(result, BinaryOperatorType.Multiply, false); case ExpressionType.MultiplyChecked: return VisitBinaryOperator(result, BinaryOperatorType.Multiply, true); case ExpressionType.Divide: return VisitBinaryOperator(result, BinaryOperatorType.Divide, false); case ExpressionType.Modulo: return VisitBinaryOperator(result, BinaryOperatorType.Modulus, false); case ExpressionType.And: return VisitBinaryOperator(result, BinaryOperatorType.BitwiseAnd); case ExpressionType.AndAlso: return VisitConditionalOperator(result, BinaryOperatorType.BitwiseAnd); case ExpressionType.Or: return VisitBinaryOperator(result, BinaryOperatorType.BitwiseOr); case ExpressionType.OrElse: return VisitConditionalOperator(result, BinaryOperatorType.BitwiseOr); case ExpressionType.ExclusiveOr: return VisitBinaryOperator(result, BinaryOperatorType.ExclusiveOr); case ExpressionType.Not: return VisitUnaryOperator(result, UnaryOperatorType.Not); // case ExpressionType.OnesComplement: case ExpressionType.LeftShift: return VisitBinaryOperator(result, BinaryOperatorType.ShiftLeft); case ExpressionType.RightShift: return VisitBinaryOperator(result, BinaryOperatorType.ShiftRight); case ExpressionType.Equal: return VisitBinaryOperator(result, BinaryOperatorType.Equality); case ExpressionType.NotEqual: return VisitBinaryOperator(result, BinaryOperatorType.InEquality); case ExpressionType.GreaterThan: return VisitBinaryOperator(result, BinaryOperatorType.GreaterThan); case ExpressionType.GreaterThanOrEqual: return VisitBinaryOperator(result, BinaryOperatorType.GreaterThanOrEqual); case ExpressionType.LessThan: return VisitBinaryOperator(result, BinaryOperatorType.LessThan); case ExpressionType.LessThanOrEqual: return VisitBinaryOperator(result, BinaryOperatorType.LessThanOrEqual); case ExpressionType.Conditional: return VisitTernaryOperator(result); default: throw new GetValueException("Unsupported operator: " + result.OperatorType); } }
public ArgumentsInfo(IEmitter emitter, UnaryOperatorExpression unaryOperatorExpression, OperatorResolveResult operatorResolveResult) { this.Emitter = emitter; this.Expression = unaryOperatorExpression; this.OperatorResolveResult = operatorResolveResult; if (operatorResolveResult.UserDefinedOperatorMethod != null) { this.BuildOperatorArgumentsList(new Expression[] { unaryOperatorExpression.Expression }); this.BuildOperatorTypedArguments(); } else { this.ArgumentsExpressions = new Expression[] { unaryOperatorExpression.Expression }; this.ArgumentsNames = new string[] { "arg" }; this.CreateNamedExpressions(this.ArgumentsNames, this.ArgumentsExpressions); } }
public ArgumentsInfo(IEmitter emitter, UnaryOperatorExpression unaryOperatorExpression, OperatorResolveResult operatorResolveResult, IMethod method) { this.Emitter = emitter; this.Expression = unaryOperatorExpression; this.OperatorResolveResult = operatorResolveResult; this.BuildOperatorArgumentsList(new Expression[] { unaryOperatorExpression.Expression }, operatorResolveResult.UserDefinedOperatorMethod ?? method); this.BuildOperatorTypedArguments(); }
Value VisitBinaryOperator(OperatorResolveResult result, BinaryOperatorType operatorType, bool checkForOverflow = false) { Debug.Assert(result.Operands.Count == 2); Debug.Assert(operatorType != BinaryOperatorType.ConditionalAnd && operatorType != BinaryOperatorType.ConditionalOr && operatorType != BinaryOperatorType.NullCoalescing); var lhs = Convert(result.Operands[0]).GetPermanentReference(evalThread); var rhs = Convert(result.Operands[1]).GetPermanentReference(evalThread); if (result.UserDefinedOperatorMethod != null) return InvokeMethod(null, result.UserDefinedOperatorMethod, lhs, rhs); var lhsRR = lhs.ToResolveResult(context); var rhsRR = rhs.ToResolveResult(context); CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow); var val = resolver.ResolveBinaryOperator(operatorType, lhsRR, rhsRR); if (val.IsCompileTimeConstant) return Convert(val); if (operatorType == BinaryOperatorType.Add && (lhsRR.Type.IsKnownType(KnownTypeCode.String) || rhsRR.Type.IsKnownType(KnownTypeCode.String))) { var method = debuggerTypeSystem.FindType(KnownTypeCode.String) .GetMethods(m => m.Name == "Concat" && m.Parameters.Count == 2) .Single(m => m.Parameters.All(p => p.Type.IsKnownType(KnownTypeCode.Object))); return InvokeMethod(null, method, lhs, rhs); } throw new InvalidOperationException(); }
Value VisitUnaryOperator(OperatorResolveResult result, UnaryOperatorType operatorType, bool checkForOverflow = false) { Debug.Assert(result.Operands.Count == 1); var operand = Convert(result.Operands[0]).ToResolveResult(context); CSharpResolver resolver = new CSharpResolver(debuggerTypeSystem).WithCheckForOverflow(checkForOverflow); var val = resolver.ResolveUnaryOperator(operatorType, operand); if (val.IsCompileTimeConstant) return Convert(val); throw new InvalidOperationException(); }
private JsNode Unary(OperatorResolveResult res) { if (res.UserDefinedOperatorMethod != null && !Sk.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition)) { var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0]); return Visit(fake); } var isProperty = false; var meRes = res.Operands[0] as MemberResolveResult; if (meRes != null && meRes.Member != null && IsEntityFunctionProperty(meRes.Member, res)) isProperty = true; JsExpression node2; if (res.OperatorType.IsAny(ExpressionType.Negate, ExpressionType.PreDecrementAssign, ExpressionType.PreIncrementAssign, ExpressionType.Not, ExpressionType.OnesComplement)) { var simpler = res.OperatorType.ExtractCompoundAssignment(); if (isProperty && simpler != null) { var fakeCs = meRes.ShallowClone().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type); node2 = VisitExpression(fakeCs); } else { node2 = new JsPreUnaryExpression { Operator = Visit(res.OperatorType), Right = VisitExpression(res.Operands[0]) }; } } else if (res.OperatorType.IsAny(ExpressionType.PostIncrementAssign, ExpressionType.PostDecrementAssign, ExpressionType.PreIncrementAssign, ExpressionType.PreDecrementAssign)) { if (isProperty) { var simpler = res.OperatorType.ExtractCompoundAssignment(); var fakeCs = meRes.ShallowClone().Binary(simpler.Value, Cs.Value(1, Project), meRes.Type); node2 = VisitExpression(fakeCs); } else { node2 = new JsPostUnaryExpression { Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]) }; } } else { throw new NotImplementedException(); } return node2; }
private JsNode Binary(OperatorResolveResult res) { if (res.UserDefinedOperatorMethod != null && !Sk.UseNativeOperatorOverloads(res.UserDefinedOperatorMethod.DeclaringTypeDefinition)) { var op2 = res.OperatorType.ExtractCompoundAssignment(); if (op2 != null) { var fakeRight = new OperatorResolveResult(res.Type, op2.Value, res.UserDefinedOperatorMethod, res.IsLiftedOperator, res.Operands); var fakeAssign = Cs.Assign(res.Operands[0], fakeRight); return Visit(fakeAssign); } var fake = Cs.InvokeMethod(res.UserDefinedOperatorMethod, null, res.Operands[0], res.Operands[1]); return Visit(fake); } if (res.OperatorType == ExpressionType.Coalesce) { var fake = Cs.Conditional(res.Operands[0].NotEqual(Cs.Null(), Project), res.Operands[0], res.Operands[1], res.Type); var fake2 = Visit(fake); fake2 = new JsParenthesizedExpression { Expression = (JsExpression)fake2 }; return fake2; } var mrr = res.Operands[0] as MemberResolveResult; if (mrr != null && mrr.Member.SymbolKind == SymbolKind.Event) { var pe = (IEvent)mrr.Member; if (res.OperatorType.IsAny(ExpressionType.AddAssign, ExpressionType.SubtractAssign)) { var accessor = res.OperatorType == ExpressionType.AddAssign ? pe.AddAccessor : pe.RemoveAccessor; var fake = new CSharpInvocationResolveResult(mrr.TargetResult, accessor, new List<ResolveResult> { res.Operands[1] }); var node6 = Visit(fake); return node6; } } if (mrr != null && IsEntityFunctionProperty(mrr.Member, res)) { var simpleOp = res.OperatorType.ExtractCompoundAssignment(); var pe = (IProperty)mrr.Member; if (simpleOp != null) { // x.Name += "Hello" -> x.Name = x.Name + "Hello" // x.Dic["Hello"] += 7 -> x.Dic["Hello"] = x.Dic["Hello"] + 7; var fake = res.Operands[0].Assign(res.Operands[0].Binary(simpleOp.Value, res.Operands[1], res.Type)); var node6 = Visit(fake); return node6; } else if (res.OperatorType == ExpressionType.Assign) { var args = new List<ResolveResult>(); if (pe.IsIndexer) { var irrOp0 = (CSharpInvocationResolveResult)res.Operands[0]; args.AddRange(irrOp0.Arguments); } args.Add(res.Operands[1]); var fake = new CSharpInvocationResolveResult(mrr.TargetResult, pe.Setter, args).AssociateWithOriginal(res); var node6 = Visit(fake); node6 = WrapSetterToReturnValueIfNeeded(res, node6); return node6; } } if (res.Operands[0] is ConversionResolveResult && res.Operands[1] is ConstantResolveResult) { var leftConv = (ConversionResolveResult)res.Operands[0]; var rightConst = (ConstantResolveResult)res.Operands[1]; if (leftConv.Conversion.IsNumericConversion && leftConv.Input.Type == Cs.CharType(Project)) { var value = ((char)(int)rightConst.ConstantValue).ToString(); var fake = Cs.Binary(leftConv.Input, res.OperatorType, Cs.Value(value, Project), leftConv.Input.Type); return Visit(fake); } } if (res.Operands[0].Type.Kind == TypeKind.Delegate && res.Operands[1].Type.Kind == TypeKind.Delegate) { if (res.OperatorType.IsAny(ExpressionType.AddAssign, ExpressionType.SubtractAssign)) { var op = res.OperatorType == ExpressionType.AddAssign ? ExpressionType.Add : ExpressionType.Subtract; var fake = Cs.Assign(res.Operands[0], Cs.Binary(res.Operands[0], op, res.Operands[1], res.Type)); var node6 = Visit(fake); return node6; } else if (res.OperatorType.IsAny(ExpressionType.Add, ExpressionType.Subtract)) { var combineMethod = Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Combine").FirstOrDefault(); var removeMethod = Project.Compilation.FindType(KnownTypeCode.Delegate).GetMethods(t => t.Name == "Remove").FirstOrDefault(); var meOp = res.OperatorType == ExpressionType.Add ? combineMethod : removeMethod; var fake = Cs.Member(null, meOp).Invoke(res.Operands[0], res.Operands[1]); var node6 = Visit(fake); return node6; } } var node5 = new JsBinaryExpression { Operator = Visit(res.OperatorType), Left = VisitExpression(res.Operands[0]), Right = VisitExpression(res.Operands[1]) }; if (res.OperatorType == ExpressionType.Equal && node5.Operator == "==") { var att = Compiler.GetJsExportAttribute(); if (att != null && att.UseExactEquals) node5.Operator = "==="; } if (res.OperatorType == ExpressionType.NotEqual && node5.Operator == "!=") { var att = Compiler.GetJsExportAttribute(); if (att != null && att.UseExactEquals) node5.Operator = "!=="; } return node5; }
protected bool ResolveOperator(BinaryOperatorExpression binaryOperatorExpression, OperatorResolveResult orr) { var method = orr != null ? orr.UserDefinedOperatorMethod : null; if (method != null) { var inline = this.Emitter.GetInline(method); if (!string.IsNullOrWhiteSpace(inline)) { new InlineArgumentsBlock(this.Emitter, new ArgumentsInfo(this.Emitter, binaryOperatorExpression, orr, method), inline).Emit(); return true; } else if (!this.Emitter.Validator.IsIgnoreType(method.DeclaringTypeDefinition)) { string name = OverloadsCollection.Create(this.Emitter, method).GetOverloadName(); if(Helpers.GetOperatorMapping(name) != null) { return false; } if (orr.IsLiftedOperator) { this.Write(Bridge.Translator.Emitter.ROOT + ".Nullable."); string action = "lift"; switch (this.BinaryOperatorExpression.Operator) { case BinaryOperatorType.GreaterThan: action = "liftcmp"; break; case BinaryOperatorType.GreaterThanOrEqual: action = "liftcmp"; break; case BinaryOperatorType.Equality: action = "lifteq"; break; case BinaryOperatorType.InEquality: action = "liftne"; break; case BinaryOperatorType.LessThan: action = "liftcmp"; break; case BinaryOperatorType.LessThanOrEqual: action = "liftcmp"; break; } this.Write(action + "("); } this.Write(BridgeTypes.ToJsName(method.DeclaringType, this.Emitter)); this.WriteDot(); this.Write(name); if (orr.IsLiftedOperator) { this.WriteComma(); } else { this.WriteOpenParentheses(); } new ExpressionListBlock(this.Emitter, new Expression[] { binaryOperatorExpression.Left, binaryOperatorExpression.Right }, null).Emit(); this.WriteCloseParentheses(); return true; } } return false; }
private object GetConstValue(OperatorResolveResult orr, bool isLeft, bool isChar) { var result = isLeft ? orr.Operands.First() : orr.Operands.Last(); if(result.IsCompileTimeConstant) { return WrapConstValue(result.ConstantValue); } ConversionResolveResult rr = result as ConversionResolveResult; if(rr != null && rr.Input.IsCompileTimeConstant) { if(isChar) { return isLeft ? this.BinaryOperatorExpression.Left.ToString() : this.BinaryOperatorExpression.Right.ToString(); } else if(rr.Input.Type.Kind == TypeKind.Enum) { MemberResolveResult reslut = (MemberResolveResult)rr.Input; return "\"" + reslut.Member.Name + "\""; } return WrapConstValue(rr.Input.ConstantValue); } return null; }
private JsNode WrapSetterToReturnValueIfNeeded(OperatorResolveResult res, JsNode node2) { return Importer.WrapSetterToReturnValueIfNeeded(res, node2); }
IEnumerable<ICompletionData> CreateCompletionData(TextLocation location, ResolveResult resolveResult, AstNode resolvedNode, CSharpResolver state, Func<IType, IType> typePred = null) { if (resolveResult == null /* || resolveResult.IsError*/) { return null; } var lookup = new MemberLookup( ctx.CurrentTypeDefinition, Compilation.MainAssembly ); if (resolveResult is NamespaceResolveResult) { var nr = (NamespaceResolveResult)resolveResult; var namespaceContents = new CompletionDataWrapper(this); foreach (var cl in nr.Namespace.Types) { if (!lookup.IsAccessible(cl, false)) continue; IType addType = typePred != null ? typePred(cl) : cl; if (addType != null) namespaceContents.AddType(addType, false); } foreach (var ns in nr.Namespace.ChildNamespaces) { namespaceContents.AddNamespace(lookup, ns); } return namespaceContents.Result; } IType type = resolveResult.Type; if (type.Namespace == "System" && type.Name == "Void") return null; if (resolvedNode.Parent is PointerReferenceExpression && (type is PointerType)) { resolveResult = new OperatorResolveResult(((PointerType)type).ElementType, System.Linq.Expressions.ExpressionType.Extension, resolveResult); } //var typeDef = resolveResult.Type.GetDefinition(); var result = new CompletionDataWrapper(this); bool includeStaticMembers = false; if (resolveResult is LocalResolveResult) { if (resolvedNode is IdentifierExpression) { var mrr = (LocalResolveResult)resolveResult; includeStaticMembers = mrr.Variable.Name == mrr.Type.Name; } } if (resolveResult is TypeResolveResult && type.Kind == TypeKind.Enum) { foreach (var field in type.GetFields ()) { if (!lookup.IsAccessible(field, false)) continue; result.AddMember(field); } return result.Result; } bool isProtectedAllowed = resolveResult is ThisResolveResult ? true : lookup.IsProtectedAccessAllowed(type); bool skipNonStaticMembers = (resolveResult is TypeResolveResult); if (resolveResult is MemberResolveResult && resolvedNode is IdentifierExpression) { var mrr = (MemberResolveResult)resolveResult; includeStaticMembers = mrr.Member.Name == mrr.Type.Name; TypeResolveResult trr; if (state.IsVariableReferenceWithSameType( resolveResult, ((IdentifierExpression)resolvedNode).Identifier, out trr )) { if (currentMember != null && mrr.Member.IsStatic ^ currentMember.IsStatic) { skipNonStaticMembers = true; if (trr.Type.Kind == TypeKind.Enum) { foreach (var field in trr.Type.GetFields ()) { if (lookup.IsAccessible(field, false)) result.AddMember(field); } return result.Result; } } } // ADD Aliases var scope = ctx.CurrentUsingScope; for (var n = scope; n != null; n = n.Parent) { foreach (var pair in n.UsingAliases) { if (pair.Key == mrr.Member.Name) { foreach (var r in CreateCompletionData (location, pair.Value, resolvedNode, state)) { if (r is IEntityCompletionData && ((IEntityCompletionData)r).Entity is IMember) { result.AddMember((IMember)((IEntityCompletionData)r).Entity); } else { result.Add(r); } } } } } } if (resolveResult is TypeResolveResult && (resolvedNode is IdentifierExpression || resolvedNode is MemberReferenceExpression)) { includeStaticMembers = true; } // Console.WriteLine ("type:" + type +"/"+type.GetType ()); // Console.WriteLine ("current:" + ctx.CurrentTypeDefinition); // Console.WriteLine ("IS PROT ALLOWED:" + isProtectedAllowed + " static: "+ includeStaticMembers); // Console.WriteLine (resolveResult); // Console.WriteLine ("node:" + resolvedNode); // Console.WriteLine (currentMember != null ? currentMember.IsStatic : "currentMember == null"); if (resolvedNode.Annotation<ObjectCreateExpression>() == null) { //tags the created expression as part of an object create expression. /* var filteredList = new List<IMember>(); foreach (var member in type.GetMembers ()) { filteredList.Add(member); } foreach (var member in filteredList) { // Console.WriteLine ("add:" + member + "/" + member.IsStatic); result.AddMember(member); }*/ foreach (var member in lookup.GetAccessibleMembers (resolveResult)) { if (member.SymbolKind == SymbolKind.Indexer || member.SymbolKind == SymbolKind.Operator || member.SymbolKind == SymbolKind.Constructor || member.SymbolKind == SymbolKind.Destructor) { continue; } if (resolvedNode is BaseReferenceExpression && member.IsAbstract) { continue; } if (member is IType) { if (resolveResult is TypeResolveResult || includeStaticMembers) { if (!lookup.IsAccessible(member, isProtectedAllowed)) continue; result.AddType((IType)member, false); continue; } } bool memberIsStatic = member.IsStatic; if (!includeStaticMembers && memberIsStatic && !(resolveResult is TypeResolveResult)) { // Console.WriteLine ("skip static member: " + member.FullName); continue; } var field = member as IField; if (field != null) { memberIsStatic |= field.IsConst; } if (!memberIsStatic && skipNonStaticMembers) { continue; } if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") { continue; } if (member.SymbolKind == SymbolKind.Operator) { continue; } if (member is IMember) { result.AddMember((IMember)member); } } } if (!(resolveResult is TypeResolveResult || includeStaticMembers)) { foreach (var meths in state.GetExtensionMethods (type)) { foreach (var m in meths) { if (!lookup.IsAccessible(m, isProtectedAllowed)) continue; result.AddMember(new ReducedExtensionMethod(m)); } } } // IEnumerable<object> objects = resolveResult.CreateResolveResult (dom, resolver != null ? resolver.CallingMember : null); // CompletionDataCollector col = new CompletionDataCollector (this, dom, result, Document.CompilationUnit, resolver != null ? resolver.CallingType : null, location); // col.HideExtensionParameter = !resolveResult.StaticResolve; // col.NamePrefix = expressionResult.Expression; // bool showOnlyTypes = expressionResult.Contexts.Any (ctx => ctx == ExpressionContext.InheritableType || ctx == ExpressionContext.Constraints); // if (objects != null) { // foreach (object obj in objects) { // if (expressionResult.ExpressionContext != null && expressionResult.ExpressionContext.FilterEntry (obj)) // continue; // if (expressionResult.ExpressionContext == ExpressionContext.NamespaceNameExcepted && !(obj is Namespace)) // continue; // if (showOnlyTypes && !(obj is IType)) // continue; // CompletionData data = col.Add (obj); // if (data != null && expressionResult.ExpressionContext == ExpressionContext.Attribute && data.CompletionText != null && data.CompletionText.EndsWith ("Attribute")) { // string newText = data.CompletionText.Substring (0, data.CompletionText.Length - "Attribute".Length); // data.SetText (newText); // } // } // } return result.Result; }
private void VisitStringConcat(OperatorResolveResult orr, bool isLeft, bool isChar) { object constValue = GetConstValue(orr, isLeft, isChar); if(constValue != null) { this.Write(constValue); } else { var express = isLeft ? this.BinaryOperatorExpression.Left : this.BinaryOperatorExpression.Right; if(isChar) { this.Write("string.char"); this.WriteOpenParentheses(); express.AcceptVisitor(this.Emitter); this.WriteCloseParentheses(); } else if(express is IdentifierExpression || express is InvocationExpression) { var resolverResult = this.Emitter.Resolver.ResolveNode(express, this.Emitter); if(resolverResult.Type.Kind == TypeKind.Struct) { express.AcceptVisitor(this.Emitter); } else if(resolverResult.Type.Kind == TypeKind.Enum) { TransformCtx.ExportEnums.Add(resolverResult.Type); this.Write("System.Enum.toString"); this.WriteOpenParentheses(); express.AcceptVisitor(this.Emitter); this.WriteComma(); string typeName = BridgeTypes.ToJsName(resolverResult.Type, this.Emitter); this.Write(typeName); this.WriteCloseParentheses(); } else { this.Write("System.strconcat"); this.WriteOpenParentheses(); express.AcceptVisitor(this.Emitter); this.WriteCloseParentheses(); } } else { express.AcceptVisitor(this.Emitter); } } }