public PostfixTemplateInfo TryCreateInfo(CSharpPostfixTemplateContext context) { if (context.IsPreciseMode) { foreach (var expressionContext in context.Expressions) { var castExpression = CastExpressionNavigator.GetByOp(expressionContext.Expression); if (castExpression == null) { continue; // available in auto over cast expressions } var expression = ParenthesizedExpressionNavigator.GetByExpression(castExpression); if (expression != null) { continue; // not already parenthesized } return(new PostfixTemplateInfo("par", expressionContext)); } return(null); } var expressions = CSharpPostfixUtis.FindExpressionWithValuesContexts(context); if (expressions.Length != 0) { return(new PostfixTemplateInfo("par", expressions)); } return(null); }
public PostfixTemplateInfo TryCreateInfo(CSharpPostfixTemplateContext context) { if (context.IsPreciseMode) { return(null); } var expressions = CSharpPostfixUtis.FindExpressionWithValuesContexts(context); if (expressions.Length == 0) { return(null); } return(new PostfixTemplateInfo("cast", expressions)); }
public PostfixTemplateInfo TryCreateInfo(CSharpPostfixTemplateContext context) { var expressionContext = context.TypeExpression ?? context.OuterExpression; if (expressionContext == null || !expressionContext.CanBeStatement) { return(null); } var expression = expressionContext.Expression; var referencedType = expressionContext.ReferencedType; if (referencedType != null) // 'Exception.throw' case { if (context.IsPreciseMode && !IsInstantiableExceptionType(referencedType, expression)) { return(null); } return(new PostfixTemplateInfo("throw", expressionContext, target: PostfixTemplateTarget.TypeUsage)); } bool needFixWithNew; if (CheckExpressionType(expressionContext, out needFixWithNew) || !context.IsPreciseMode) { var reference = expressionContext.Expression as IReferenceExpression; if (reference != null && CSharpPostfixUtis.IsReferenceExpressionsChain(reference)) { return(new PostfixTemplateInfo("throw", expressionContext, target: PostfixTemplateTarget.TypeUsage)); } var info = new PostfixTemplateInfo("throw", expressionContext); if (needFixWithNew) { info.PutData(NeedFixWithNewKey, info); } return(info); } return(null); }
private static bool CheckExpressionType([NotNull] CSharpPostfixExpressionContext expressionContext, out bool needFixWithNew) { needFixWithNew = false; // 'new Exception().throw' case var expressionType = expressionContext.ExpressionType; if (expressionType.IsResolved) { var predefinedType = expressionContext.Expression.GetPredefinedType(); var conversionRule = expressionContext.Expression.GetTypeConversionRule(); return(expressionType.IsImplicitlyConvertibleTo(predefinedType.Exception, conversionRule)); } // 'Exception(message).new' case var invocationExpression = expressionContext.Expression as IInvocationExpression; if (invocationExpression != null) { var reference = invocationExpression.InvokedExpression as IReferenceExpression; if (reference == null || !CSharpPostfixUtis.IsReferenceExpressionsChain(reference)) { return(false); } var resolveResult = reference.Reference.Resolve().Result; var typeElement = resolveResult.DeclaredElement as ITypeElement; if (typeElement == null) { return(false); } var declaredType = TypeFactory.CreateType(typeElement, resolveResult.Substitution); if (IsInstantiableExceptionType(declaredType, expressionContext.Expression)) { needFixWithNew = true; return(true); } } return(false); }
private static bool IsConstructorInvocation([NotNull] ICSharpExpression expression) { // check for expressions like 'StringBuilder().new' var invocationExpression = expression as IInvocationExpression; if (invocationExpression == null) { return(false); } var reference = invocationExpression.InvokedExpression as IReferenceExpression; if (reference != null && CSharpPostfixUtis.IsReferenceExpressionsChain(reference)) { var resolveResult = reference.Reference.Resolve().Result; return(resolveResult.DeclaredElement is ITypeElement); } return(false); }
public PostfixTemplateInfo TryCreateInfo(CSharpPostfixTemplateContext context) { if (context.IsPreciseMode) { return(null); } // disable .arg template if .arg hotspot is enabled now var textControl = context.ExecutionContext.TextControl; if (textControl.GetData(PostfixArgTemplateExpansion) != null) { return(null); } var expressions = CSharpPostfixUtis.FindExpressionWithValuesContexts(context, IsNiceArgument); if (expressions.Length == 0) { return(null); } return(new PostfixTemplateInfo("arg", expressions)); }
private IList <CSharpPostfixExpressionContext> BuildExpressions( [NotNull] ITreeNode reference, [CanBeNull] out CSharpPostfixExpressionContext typeContext) { // build expression contexts var expressionContexts = new List <CSharpPostfixExpressionContext>(); var endOffset = ToDocumentRange(reference).TextRange.EndOffset; var previousStartOffset = -1; for (ITreeNode node = myInnerExpression; node != null; node = node.Parent) { if (node is ICSharpStatement) { break; } var expression = node as ICSharpExpression; if (expression == null || expression == reference) { continue; } var expressionRange = ExecutionContext.GetDocumentRange(expression); if (!expressionRange.IsValid()) { break; // stop when out of generated } if (expressionRange.TextRange.EndOffset > endOffset) { break; // stop when 'a.var + b' } if (expressionRange.TextRange.StartOffset == previousStartOffset) { break; // track start offset is changes when we are going up } previousStartOffset = expressionRange.TextRange.StartOffset; // skip relational expressions like this: 'List<int.{here}>' if (CSharpPostfixUtis.IsRelationalExpressionWithTypeOperand(expression)) { continue; } var expressionContext = new CSharpPostfixExpressionContext(this, expression); if (expressionContext.ReferencedElement is ITypeElement) { // skip types that are parts of 'List<T.>'-like expressions if (!CSharpPostfixUtis.CanTypeBecameExpression(myInnerExpression)) { continue; } if (myTypeExpression != null) { break; // should never happens } typeContext = expressionContext; // yeah, time to stop return(EmptyList <CSharpPostfixExpressionContext> .InstanceList); } expressionContexts.Add(expressionContext); if (expressionContext.CanBeStatement) { break; } } typeContext = null; return(expressionContexts.AsReadOnly()); }
private static PostfixTemplateInfo TryCreateExpressionInfo([NotNull] CSharpPostfixTemplateContext context) { var expressionContext = context.InnerExpression; if (expressionContext == null) { return(null); } var invocationExpression = expressionContext.Expression as IInvocationExpression; if (invocationExpression != null) { var reference = invocationExpression.InvokedExpression as IReferenceExpression; if (reference != null) { var resolveResult = reference.Reference.Resolve(); var declaredElement = resolveResult.DeclaredElement; if (context.IsPreciseMode) { var typeElement = declaredElement as ITypeElement; if (typeElement != null && TypeUtils.IsUsefulToCreateWithNew(typeElement)) { var canInstantiate = TypeUtils.CanInstantiateType(typeElement, reference); if (canInstantiate != CanInstantiate.No) { return(new PostfixTemplateInfo("new", expressionContext)); } } } else if (declaredElement == null || declaredElement is ITypeElement) { if (CSharpPostfixUtis.IsReferenceExpressionsChain(reference)) { return(new PostfixTemplateInfo("new", expressionContext)); } } } return(null); } if (!context.IsPreciseMode) // UnresolvedType.new { var reference = expressionContext.Expression as IReferenceExpression; if (reference != null && CSharpPostfixUtis.IsReferenceExpressionsChain(reference)) { var resolveResult = reference.Reference.Resolve(); var declaredElement = resolveResult.DeclaredElement; if (declaredElement == null || declaredElement is ITypeElement) { // hasRequiredArguments: true return(new PostfixTemplateInfo("new", expressionContext, PostfixTemplateTarget.TypeUsage)); } } } return(null); }