public VariableDefintionStatement(string name, DataType type, ProgramState state, IExpression right) { Variable = new Variable(name, type); state.DefineVariable(Variable); if (Variable.Type == DataType.Int) { if (right.Type != DataType.Int) { throw new CompilerException("Cannot implicitly convert " + Right.Type + " to Int."); } Right = right.As <int>(); } else if (Variable.Type == DataType.Float) { if (right.Type == DataType.String) { throw new CompilerException("Cannot implicitly convert String to Float."); } Right = right.As <double>(); } else { Right = right.As <string>(); } }
public static IExpression Create(IExpression left, IExpression right) { if (left.Type == DataType.String || right.Type == DataType.String) { throw new CompilerException("Cannot apply '%' operator to an operand of type String."); } else if (left.Type == DataType.Float || right.Type == DataType.Float) { return(new FloatModuloExpression(left.As <double>(), right.As <double>())); } else { return(new IntModuloExpression(left.As <int>(), right.As <int>())); } }
public static IExpression Create(IExpression right) { if (right.Type == DataType.String) { throw new CompilerException("The unary '-' operator does not support String operands."); } else if (right.Type == DataType.Float) { return(new FloatNegateExpression(right.As <double>())); } else { return(new IntNegateExpression(right.As <int>())); } }
public static IExpression Create(IExpression left, IExpression right) { if (left.Type == DataType.String || right.Type == DataType.String) { return(new StringAdditionExpression(left.As <string>(), right.As <string>())); } else if (left.Type == DataType.Float || right.Type == DataType.Float) { return(new FloatAdditionExpression(left.As <double>(), right.As <double>())); } else { return(new IntAdditionExpression(left.As <int>(), right.As <int>())); } }
/// <summary> /// Whether the <paramref name="node"/> is an <code>importFrom(...)</code> or <code>importFile(...)</code> with the required number of arguments (i.e. with 1 argument). /// </summary> public static bool IsImportCall( [NotNull] this INode node, out ICallExpression callExpression, out DScriptImportFunctionKind importKind, out IExpression argumentAsExpression, out ILiteralExpression argumentAsLiteral) { Contract.Requires(node != null); const int parameterCount = 1; callExpression = node.As <ICallExpression>(); var expressionIdentifier = callExpression?.Expression.As <IIdentifier>(); if ( (expressionIdentifier?.Text == Names.InlineImportFunction || expressionIdentifier?.Text == Names.InlineImportFileFunction) && (callExpression.TypeArguments == null || callExpression.TypeArguments.Count == 0) && callExpression.Arguments.Length >= parameterCount) { importKind = expressionIdentifier.Text == Names.InlineImportFunction ? DScriptImportFunctionKind.ImportFrom : DScriptImportFunctionKind.ImportFile; argumentAsExpression = callExpression.Arguments[0]; argumentAsLiteral = argumentAsExpression.As <ILiteralExpression>(); return(true); } importKind = DScriptImportFunctionKind.None; argumentAsExpression = null; argumentAsLiteral = null; return(false); }
private static INode ComputeFix(string formatFunction, IExpression arg) { // Short-circuit common single string var stringLiteralArgument = arg.As <IStringLiteral>(); if (stringLiteralArgument != null) { return(new TaggedTemplateExpression(formatFunction, stringLiteralArgument.Text)); } var expressions = new List <IExpression>(); TryFlattenAdditions(arg, expressions); var firstStringLiteral = expressions[0].As <IStringLiteral>(); Contract.Assert(firstStringLiteral != null, "Invariant of TryFlattenAdditions is that the first expression is a StringLiteral. Bug in TryFlattenAdditions"); var firstText = firstStringLiteral?.Text; // Another common case where after flattening we have a single string if (expressions.Count == 1) { return(new TaggedTemplateExpression(formatFunction, firstText)); } var spans = new List <ITemplateSpan>(); for (int i = 1; i < expressions.Count; i++) { var first = expressions[i]; Contract.Assert( first.As <IStringLiteral>() == null, "Cannot have two string literals in sequence in this list. Bug in TryFlattenAdditions"); // Check if second is a string literal expression string second = string.Empty; if (i < expressions.Count - 1) { var secondAsString = expressions[i + 1].As <IStringLiteral>(); if (secondAsString != null) { // We found a string. make it the second and skip the node second = secondAsString.Text; i++; } } var last = i == expressions.Count - 1; spans.Add(new TemplateSpan(first, second, last)); } return(new TaggedTemplateExpression { Tag = new Identifier(formatFunction), TemplateExpression = new TemplateExpression( firstText, spans.ToArray()), }); }
private static int?TryExtractInt(IExpression expression) { if (expression == null) { return(null); } switch (expression.Kind) { case TypeScript.Net.Types.SyntaxKind.NumericLiteral: int parsed; if (int.TryParse(expression.As <ILiteralExpression>().Text, out parsed)) { return(parsed); } return(null); case TypeScript.Net.Types.SyntaxKind.PrefixUnaryExpression: var prefixExpression = expression.As <IPrefixUnaryExpression>(); var result = TryExtractInt(prefixExpression.Operand); if (!result.HasValue) { return(null); } switch (prefixExpression.Operator) { case TypeScript.Net.Types.SyntaxKind.MinusToken: return(0 - result); case TypeScript.Net.Types.SyntaxKind.PlusToken: return(result); case TypeScript.Net.Types.SyntaxKind.TildeToken: case TypeScript.Net.Types.SyntaxKind.ExclamationToken: case TypeScript.Net.Types.SyntaxKind.MinusMinusToken: case TypeScript.Net.Types.SyntaxKind.PlusPlusToken: default: return(null); } default: return(null); } }
private static IIdentifier UnwrapIdentifier(IExpression expression) { var identifier = expression.As <IIdentifier>(); if (identifier != null) { return(identifier); } var callExpression = expression.As <ICallExpression>(); if (callExpression != null) { return(UnwrapIdentifier(callExpression.Expression)); } return(null); }
private static void CheckImportOrExportClause(INode node, DiagnosticContext context) { IExpression specifier = node.GetModuleSpecifier(); var literalExpression = specifier?.As <IStringLiteral>(); // There is a lint rule that enforces this, but it might have not run yet if (literalExpression == null) { return; } CheckImportedModule(node, literalExpression.Text, context); }
/// <summary> /// Attempts to flatten multiple additions into a list of expressions. /// If multiple string literals are added, then we already concat them here to avoid another pass. /// </summary> private static void TryFlattenAdditions(IExpression arg, List <IExpression> expressions) { var binOp = arg.As <IBinaryExpression>(); if (binOp != null) { if (binOp.OperatorToken.Kind == TypeScript.Net.Types.SyntaxKind.PlusToken) { TryFlattenAdditions(binOp.Left, expressions); TryFlattenAdditions(binOp.Right, expressions); return; } } // Auto-concat string literals var argExprString = arg.As <IStringLiteral>(); if (argExprString != null && expressions.Count > 0) { var lastExpr = expressions[expressions.Count - 1]; var lastExprString = lastExpr.As <IStringLiteral>(); if (lastExprString != null) { expressions[expressions.Count - 1] = new LiteralExpression(lastExprString.Text + argExprString.Text); return; } } // Format string structure always starts with a string, insert empty string if none here yet. if (argExprString == null && expressions.Count == 0) { expressions.Add(new LiteralExpression(string.Empty)); } expressions.Add(arg); return; }
/// <summary> /// Validates that importFile is always passed a file literal /// </summary> protected override void DoValidateImportFile(IExpression argument, ILiteralExpression stringLiteral, DiagnosticContext context) { (var interpolationKind, ILiteralExpression literal, _, _) = argument.As <ITaggedTemplateExpression>(); if (interpolationKind != InterpolationKind.FileInterpolation || literal == null) { // Must pass a file path literal to importFile context.Logger.ReportImportFileNotPassedAFileLiteral( context.LoggingContext, argument.LocationForLogging(context.SourceFile), argument.GetFormattedText()); } CheckForFilesThatExposeNothing(literal?.Text, argument, Names.InlineImportFileFunction, context); }
protected void ValidateImportFile(IExpression argument, [CanBeNull] ILiteralExpression stringLiteral, DiagnosticContext context) { DoValidateImportFile(argument, stringLiteral, context); (_, ILiteralExpression literal, _, _) = argument.As <ITaggedTemplateExpression>(); string text = stringLiteral?.Text ?? literal?.Text; if (text != null && text.IndexOfAny(ImportPathHelpers.InvalidPathChars) != -1) { context.Logger.ReportModuleSpecifierContainsInvalidCharacters( context.LoggingContext, argument.LocationForLogging(context.SourceFile), text, ImportPathHelpers.InvalidPathCharsText); } }
private static void CheckProjectLikeImportsOrExportsNotInV2Specs(INode node, DiagnosticContext context) { IExpression specifier = node.GetModuleSpecifier(); var literalExpression = specifier?.As <IStringLiteral>(); // There is a lint rule that enforces this, but it might have not run yet if (literalExpression == null || literalExpression.LiteralKind == LiteralExpressionKind.None) { return; } // If the spec belongs to a module with implicit references, then project-like imports are not allowed if (context.Workspace.SpecBelongsToImplicitSemanticsModule(context.SourceFile.GetAbsolutePath(context.PathTable)) && !ModuleReferenceResolver.IsModuleReference(literalExpression)) { context.Logger.ReportProjectLikeImportOrExportNotAllowedInModuleWithImplicitSemantics( context.LoggingContext, node.LocationForLogging(context.SourceFile), specifier.GetFormattedText()); } }
public PrintStatement(IExpression expression) { Expression = expression.As <string>(); }