/// <summary> /// This method returns true if the type expression passed as argumen can be a type expression able to promote to a String if it is combined /// with another typeExpression, ussing as operand: + or += /// </summary> /// <param name="tE">tE TypeExpression passed as argument</param> /// <returns>true if the type expression passed as argumen can be a type expression able to promote to a String if it is combined /// with another typeExpression, ussing as operand: + or += /// false otherwise. /// </returns> protected bool promotableToStringInAddition(TypeExpression tE) { return((int)tE.AcceptOperation(new PromotionLevelOperation(DoubleType.Instance), null) != -1 || (bool)tE.AcceptOperation(new EquivalentOperation(CharType.Instance), null) || (bool)tE.AcceptOperation(new EquivalentOperation(StringType.Instance), null) || (bool)tE.AcceptOperation(new EquivalentOperation(NullType.Instance), null)); }
public override object Exec(IntType firstOperand, object arg) { if ((int)secondOperand.AcceptOperation(new PromotionLevelOperation(DoubleType.Instance), arg) != -1) { return(BoolType.Instance); } //? quedaría menos lioso new BinaryAritmeticalOperation(iTE, ...).exec(secondOperand) return(secondOperand.AcceptOperation(new RelationalOperation(firstOperand, this.relationalOperator, this.methodAnalyzed, this.showErrorMessage, this.location), arg)); }
/// <summary> /// The first Operand is a Double so the second must be promotable to a DoubleType so the whole operation must have sense. /// Implements a double dispatch pattern. /// </summary> /// <param name="firstOperand">A double type to perform a binary arithmetica operation with. The second operate have to be promotable /// to Double, cause is the grater integral value.</param> /// <returns>A TypeExpression if the operation makes sense, otherwise if showMessages is true, an error is raised</returns> public override object Exec(DoubleType firstOperand, object arg) { if ((int)this.secondOperand.AcceptOperation(new PromotionLevelOperation(firstOperand), arg) != -1) { return(DoubleType.Instance); } if (this.binaryOperator.Equals(ArithmeticOperator.Plus) && (bool)this.secondOperand.AcceptOperation(new EquivalentOperation(StringType.Instance), arg)) { return(StringType.Instance); } // We rely in arithmetic conmutativiness to perform a cross recursion. Could it be dangerous? return(secondOperand.AcceptOperation(ArithmeticalOperation.Create(firstOperand, this.binaryOperator, this.methodAnalyzed, this.showErrorMessage, this.location), arg)); }
public override object Exec(TypeExpression from, object arg) { if ((int)from.AcceptOperation(new PromotionLevelOperation(this.to), arg) == -1) { return(ReportError(from)); } return(to); }
public override object Exec(IntersectionType caller, object arg) { TypeExpression method = caller.overloadResolution(this.arguments, this.location); if (method == null) { return(null); } return(method.AcceptOperation(this, arg)); }
public override object Exec(TypeVariable tv, object arg) // this is a likely array { TypeExpression subtitution = tv.Substitution; if (subtitution == null) { return(emptyAccessModifier); } return(subtitution.AcceptOperation(this, null)); }
/// <summary> /// If the cast is possible it returns the value of the field "to". If there is an error and showMessages is true an error is raised. /// </summary> /// <param name="from">The type from we want to cast.</param> /// <returns>The TypeExpression castType if the casting is possible. Otherwise. If there is an error and showMessages /// is true an error is raised. /// </returns> public override object Exec(TypeExpression from, object arg) { if (this.castType == null) { return(null); } if (((int)castType.AcceptOperation(new PromotionLevelOperation(from), arg) != -1) || ((int)from.AcceptOperation(new PromotionLevelOperation(castType), arg) != -1)) { return(castType); } return(ReportError(from)); }
public override object Exec(TypeExpression operand, object arg) { if (this.union.Count == 1) { return(null); } string notThisType = this.codeGenerator.NewLabel; string endLabel = this.codeGenerator.NewLabel; operand.AcceptOperation(new CGRuntimeIsInstructionOperation <T>(this.indent, this.codeGenerator), arg); this.codeGenerator.brfalse(this.indent, notThisType); operand.AcceptOperation(new CGRuntimeFreshTEPromotionOperation <T>(this.indent, this.codeGenerator), arg); this.codeGenerator.br(this.indent, endLabel); this.codeGenerator.WriteLabel(this.indent, notThisType); // As the expected type is not an String, we throw an exception this.codeGenerator.WriteThrowException(this.indent, new WrongDynamicTypeExceptionManager()); this.codeGenerator.AddExceptionCode(new WrongDynamicTypeExceptionManager()); this.codeGenerator.WriteLabel(this.indent, endLabel); return(null); }
/// <summary> /// General behaviour of the operation As explained in the Class summary /// </summary> /// <param name="firstTypeExpression">the TypeExpression to compare with the attribute secondTypeExpression</param> /// <param name="arg">not used</param> /// <returns>the major type of both type expressions or null if there's no major type.</returns> public override object Exec(TypeExpression firstTypeExpression, object arg) { if ((int)firstTypeExpression.AcceptOperation(new PromotionLevelOperation(this.secondTypeExpression), null) >= 0) { return(this.secondTypeExpression); } if ((int)this.secondTypeExpression.AcceptOperation(new PromotionLevelOperation(firstTypeExpression), null) >= 0) { return(firstTypeExpression); } return(null); }
/// <summary> /// The first Operand is a Double so the second must be promotable to a DoubleType so the whole operation must have sense. /// Implements a double dispatch pattern. /// </summary> /// <param name="firstOperand">A double type to perform a binary arithmetica operation with. The second operate have to be promotable /// to Double, cause is the grater integral value.</param> /// <returns>A TypeExpression if the operation makes sense, otherwise if showMessages is true, an error is raised</returns> public override object Exec(DoubleType firstOperand, object arg) { if ((int)this.secondOperand.AcceptOperation(new PromotionLevelOperation(firstOperand), arg) != -1) { if (secondOperand is TypeVariable) { if (methodAnalyzed != null && ((TypeVariable)secondOperand).Substitution == null) { // * A constraint is added to the method analyzed ArithmeticConstraint constraint = new ArithmeticConstraint(firstOperand, secondOperand, binaryOperator, location); methodAnalyzed.AddConstraint(constraint); return(constraint.ReturnType); } } return(DoubleType.Instance); } if (this.binaryOperator.Equals(ArithmeticOperator.Plus) && (bool)this.secondOperand.AcceptOperation(new EquivalentOperation(StringType.Instance), arg)) { return(StringType.Instance); } // We rely in arithmetic conmutativiness to perform a cross recursion. Could it be dangerous? return(secondOperand.AcceptOperation(ArithmeticalOperation.Create(firstOperand, this.binaryOperator, this.methodAnalyzed, this.showErrorMessage, this.location), arg)); }
public override object Exec(FieldAccessExpression f, object arg) { // * 1. A message has been sent with the syntax "obj.method(...)" TypeExpression caller = this.node.ActualMethodCalled; if (caller != null) { return(caller.AcceptOperation(new CGILMethodInvocationOperation <T>( this.indent, this.visitor, this.codeGenerator, this.node, this.inheritedAttributes, this.objArgs, this.objInv), arg)); } throw new FieldAccessException(); }
/// <summary /// General behaviour of the operation As explained in the Class summary /// </summary> /// <param name="firstTypeExpression">the TypeExpression to compare with the attribute secondTypeExpression</param> /// <param name="arg">not used</param> /// <returns>the major type of both type expressions or null if there's no major type.</returns> public override object Exec(TypeExpression firstTypeExpression, object arg) { if (this.node.Operator == ArithmeticOperator.Plus && (TypeExpression.Is <StringType>(this.secondTypeExpression) || TypeExpression.Is <StringType>(firstTypeExpression) ) ) { return(StringType.Instance); } //if ( TypeExpression.Is<CharType>(firstTypeExpression) || TypeExpression.Is<CharType>(this.secondTypeExpression) ) // return IntType.Instance; return(firstTypeExpression.AcceptOperation(new MajorTypeOperation(this.secondTypeExpression), arg)); }
/// <summary> /// Assigns all the attributes in two this references, generating the appropriate constraints. /// </summary> /// <param name="classType">The type of this</param> /// <param name="typeOfThis1">The first value of this' type</param> /// <param name="typeOfThis2">The second value of this' type</param> /// <param name="methodAnalyzed">Method being analyzed</param> /// <param name="unification">WriteType of unification</param> /// <param name="actualImplicitObject">The actual implicit object</param> /// <summary> public static void AssignAttributes(UserType classType, TypeExpression typeOfThis1, TypeExpression typeOfThis2, MethodType methodAnalyzed, SortOfUnification unification, TypeExpression actualImplicitObject, Location location) { if (methodAnalyzed == null) { return; } foreach (KeyValuePair <string, AccessModifier> pair in classType.Fields) { TypeExpression fieldType = pair.Value.Type, fieldType1 = getFieldType(typeOfThis1, pair.Key), fieldType2 = getFieldType(typeOfThis2, pair.Key); TypeExpression unionType = UnionType.collect(fieldType1, fieldType2); fieldType.AcceptOperation(new AssignmentOperation(unionType, AssignmentOperator.Assign, methodAnalyzed, unification, actualImplicitObject, location), null); } }
/// Assigns all the attributes in many this references, generating the appropriate constraints. /// </summary> /// <param name="classType">The type of this</param> /// <param name="typesOfThisAfterCases">The types of this after each case</param> /// <param name="methodAnalyzed">Method being analyzed</param> /// <param name="unification">WriteType of unification</param> /// <param name="actualImplicitObject">The actual implicit object</param> public static void AssignAttributes(UserType classType, IList <TypeExpression> typesOfThisAfterCases, MethodType methodAnalyzed, SortOfUnification unification, TypeExpression actualImplicitObject, Location location) { if (methodAnalyzed == null) { return; } foreach (KeyValuePair <string, AccessModifier> pair in classType.Fields) { TypeExpression fieldType = pair.Value.Type; TypeExpression unionType = null; foreach (TypeExpression typeOfThis in typesOfThisAfterCases) { TypeExpression eachFieldType = getFieldType(typeOfThis, pair.Key); unionType = UnionType.collect(unionType, eachFieldType); } fieldType.AcceptOperation(new AssignmentOperation(unionType, AssignmentOperator.Assign, methodAnalyzed, unification, actualImplicitObject, location), null); } }
public override object Exec(ArrayType operand1, object arg) { // * Is it an array? ArrayType arrayType = TypeExpression.As <ArrayType>(this.operand2); if (arrayType != null) { return(operand1.ArrayTypeExpression.AcceptOperation(new EquivalentOperation(arrayType.ArrayTypeExpression), arg)); } // * It can be a System.Array BCLClassType bclClassType = TypeExpression.As <BCLClassType>(this.operand2); if (bclClassType.TypeInfo.IsArray) { TypeExpression elementType = TypeTable.Instance.GetType(bclClassType.TypeInfo.GetElementType().FullName, new Location()); return(elementType.AcceptOperation(new EquivalentOperation(operand1), arg)); } return(false); }
public override object Exec(TypeVariable a, object arg) // this is a likely array { TypeExpression subtitutions = a.Substitution; if (subtitutions != null) { DynVarOptions.Instance.AssignDynamism(subtitutions, a.IsDynamic); return(subtitutions.AcceptOperation(this, arg)); } if (this.methodAnalyzed != null) { // * A bracket constraint is added to the method analyzed SquareBracketConstraint bracketConstraint = new SquareBracketConstraint(a, this.index, this.location); this.methodAnalyzed.AddConstraint(bracketConstraint); // * Also a promotion constriaint of the index to IntType //index.Promotion(IntType.Instance, ArrayOperator.Indexer, methodAnalyzed, fileName, line, column); return(bracketConstraint.ReturnType); } // We are at this point the operation is invalid, report the error.? return(ReportError(a)); }
public override object Exec(BCLClassType operand1, object arg) { if (this.operand2 == null) { return(false); } if (operand1.FullName.Equals(this.operand2.FullName)) { return(true); } if ((bool)BCLClassType.BCLtoTypeSystemMapping.ContainsKey(operand1.FullName) && (bool)BCLClassType.BCLtoTypeSystemMapping[operand1.FullName].AcceptOperation(new EquivalentOperation(operand2), null)) { return(true); } if (operand1.TypeInfo.IsArray) { Type elementType = operand1.TypeInfo.GetElementType(); if (this.operand2 is ArrayType) { return(new BCLClassType(elementType.FullName, elementType).AcceptOperation(new EquivalentOperation(((ArrayType)this.operand2).ArrayTypeExpression), null)); } BCLClassType bclType = TypeExpression.As <BCLClassType>(this.operand2); if (bclType != null && bclType.TypeInfo.IsArray) { TypeExpression thisArrayType = TypeTable.Instance.GetType(operand1.TypeInfo.GetElementType().FullName, new Location()), paramArrayType = TypeTable.Instance.GetType(bclType.TypeInfo.GetElementType().FullName, new Location()); return(thisArrayType.AcceptOperation(new EquivalentOperation(paramArrayType), null)); } } return(false); }
private List <Completion> memberCompletion(ITextSnapshot snapshot, int start, int line, int column) { List <Completion> memberCompletion = new List <Completion>(); AstNode foundNode = null; //Replace '.' with ';' to avoid parse errors Span dotSpan = new Span(start, 1); snapshot = snapshot.TextBuffer.Delete(dotSpan); snapshot = snapshot.TextBuffer.Insert(dotSpan.Start, ";"); //StaDynParser parser = new StaDynParser(snapshot.TextBuffer, FileUtilities.Instance.getCurrentOpenDocumentFilePath()); //Parse source StaDynSourceFileAST parseResult;// = parser.parseSource(); StaDynParser parser = new StaDynParser(); parser.parseAll(); parseResult = ProjectFileAST.Instance.getAstFile(FileUtilities.Instance.getCurrentOpenDocumentFilePath()); //Replace ';' with '.' snapshot = snapshot.TextBuffer.Delete(dotSpan); snapshot = snapshot.TextBuffer.Insert(dotSpan.Start, "."); //parseResult = DecorateAST.Instance.completeDecorateAndUpdate(parseResult); if (parseResult == null || parseResult.Ast == null) { return(memberCompletion); } char previousChar = snapshot.GetText(start - 1, 1)[0]; column += 1; //Previous node is a MthodCall or Cast if (previousChar == ')') { //Start point is the ')', not the '.', so start-1 //foundNode = this.getCurrentInvocation(parseResult, snapshot, start - 1, line, column); foundNode = StaDynIntellisenseHelper.Instance.getCurrentInvocation(parseResult, snapshot, start - 1, line, column); if (!(foundNode is InvocationExpression) && !(foundNode is NewExpression)) { foundNode = this.getCurrentCast(parseResult, snapshot, start - 1, line, column); } } //Previous node is ArrayAcces else if (previousChar == ']') { foundNode = this.getCurrentArray(parseResult, snapshot, start, line, column); } else { //Node search //foundNode = (AstNode)parseResult.Ast.Accept(new VisitorFindNode(), new Location(Path.GetFileName(parseResult.FileName), line, column)); foundNode = (AstNode)parseResult.Ast.Accept(new VisitorFindNode(), new Location(parseResult.FileName, line, column)); } if (foundNode == null) { return(null); } TypeExpression type = (TypeExpression)foundNode.AcceptOperation(new GetNodeTypeOperation(), null); if (type == null) { return(null); } //Get the type members //double dispathcer pattern AccessModifier[] members = (AccessModifier[])type.AcceptOperation(new GetMembersOperation(), null); string displayName, description; bool duplicate = false; foreach (AccessModifier member in members) { duplicate = false; displayName = member.MemberIdentifier; description = displayName; if (member.Type != null) { //description = member.Type.FullName; description = member.Type.AcceptOperation(new GetTypeSystemName(), null) as string; if (String.IsNullOrEmpty(description)) { description = displayName; } } ImageSource image = CompletionGlyph.Instance.getImage(member.Type, this._glyphService); //Completion element = new Completion("." + displayName, "." + displayName, description, image, displayName); Completion element = new Completion(displayName, "." + displayName, description, image, displayName); //Avoid adding duplicate members foreach (Completion completion in memberCompletion) { if (completion.DisplayText == element.DisplayText) { if (completion.Description != description) { completion.Description += @" \/ " + description; } duplicate = true; break; } } if (!duplicate) { memberCompletion.Add(element); } //memberCompletion.Add(element); } //Sort the elements memberCompletion.Sort((x, y) => string.Compare(x.DisplayText, y.DisplayText)); //Remove duplicates //List<Completion> unique = new List<Completion>(memberCompletion.Distinct<Completion>(new CompletionComparer())); return(memberCompletion); }
protected override TypeExpression MajorType(TypeExpression typeExpression1, TypeExpression typeExpression2) { return((TypeExpression)typeExpression1.AcceptOperation(new MajorTypeForArithMeticOperation(typeExpression2, (ArithmeticExpression)node), null)); }
/// <summary> /// Performs an assigment operation between an boolean type and the typeExpression stored in this.rightOperand. /// The type to asign to the array must be promotable to an BoolType, and the only allowable operator is AssignmentOperator /// </summary> /// <param name="leftOperand">A BoolType to use as leftOperand in an assignment operation</param> /// <returns>The typeExpression resulting of have been doing the operation. Or an error if there is.</returns> public override object Exec(BoolType leftOperand, object arg) { return(this.op == AssignmentOperator.Assign // * if the operator is not assing raise and error, in other case, check if the second operand can be promotable to a BoolType ? rightOperand.AcceptOperation(PromotionOperation.Create(leftOperand, this.op, this.methodAnalyzed, this.location), arg) : ReportError(leftOperand)); }