예제 #1
0
        public void VisitNodes(GrapeCodeGeneratorConfiguration config)
        {
            this.config = config;
            foreach (IAstNodeVisitor visitor in nodeVisitors) {
                visitor.Config = config;
            }

            foreach (IAstNodeValidator validator in nodeValidators) {
                validator.Config = config;
            }

            VisitNodesForEntityList(config.Ast.Children);
        }
 public bool DoesTypeExist(GrapeCodeGeneratorConfiguration config, string typeName, string fileName)
 {
     GrapeClass c = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetCorrectNativeTypeName(typeName), fileName);
     return c != null;
 }
        public bool ValidateExpression(GrapeCodeGeneratorConfiguration config, GrapeExpression expression)
        {
            if (expression != null) {
                GrapeAst ast = config.Ast;
                string errorMessage = "";
                if (GrapeAstVisitor.IsTypeInTypeArray(expression.GetType(), accessExpressionValidator.NodeType)) {
                    return accessExpressionValidator.ValidateNode(expression);
                } else if (expression.GetType() == typeof(GrapeAddExpression)) {
                    GrapeAddExpression addExpression = expression as GrapeAddExpression;
                    if (!(typeCheckingUtils.DoesExpressionResolveToType(config, expression, addExpression.Left, "int_base") && typeCheckingUtils.DoesExpressionResolveToType(config, expression, addExpression.Right, "int_base", ref errorMessage)) || !(typeCheckingUtils.DoesExpressionResolveToType(config, expression, addExpression.Left, "fixed_base", ref errorMessage) && typeCheckingUtils.DoesExpressionResolveToType(config, expression, addExpression.Right, "fixed_base", ref errorMessage)) || !(typeCheckingUtils.DoesExpressionResolveToType(config, expression, addExpression.Left, "string_base", ref errorMessage) && typeCheckingUtils.DoesExpressionResolveToType(config, expression, addExpression.Right, "string_base", ref errorMessage))) {
                        errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot resolve addition expressions to the same type or addition expressions resolve to a type that is unable to be merged. " + errorMessage, FileName = expression.FileName, Entity = addExpression });
                        if (!config.ContinueOnError) {
                            return false;
                        }
                    }
                } else if (expression.GetType() == typeof(GrapeConditionalExpression)) {
                    GrapeConditionalExpression conditionalExpression = expression as GrapeConditionalExpression;
                    if (conditionalExpression.Type == GrapeConditionalExpression.GrapeConditionalExpressionType.BinaryAnd || conditionalExpression.Type == GrapeConditionalExpression.GrapeConditionalExpressionType.BinaryOr) {
                        if (!typeCheckingUtils.DoesExpressionResolveToType(config, expression, conditionalExpression.Left, "int_base", ref errorMessage) || !typeCheckingUtils.DoesExpressionResolveToType(config, expression, conditionalExpression.Right, "int_base", ref errorMessage)) {
                            errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot resolve expression to the type 'int_base'. " + errorMessage, FileName = expression.FileName, Entity = conditionalExpression });
                            if (!config.ContinueOnError) {
                                return false;
                            }
                        }
                    } else {
                        if (!typeCheckingUtils.DoesExpressionResolveToType(config, expression, conditionalExpression.Left, "bool_base", ref errorMessage) || !typeCheckingUtils.DoesExpressionResolveToType(config, expression, conditionalExpression.Right, "bool_base", ref errorMessage)) {
                            errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot resolve expression to the type 'bool_base'. " + errorMessage, FileName = expression.FileName, Entity = conditionalExpression });
                            if (!config.ContinueOnError) {
                                return false;
                            }
                        }
                    }
                } else if (expression.GetType() == typeof(GrapeMultiplicationExpression)) {
                    GrapeMultiplicationExpression multiplicationExpression = expression as GrapeMultiplicationExpression;
                    if (!(typeCheckingUtils.DoesExpressionResolveToType(config, expression, multiplicationExpression.Left, "int_base", ref errorMessage) && typeCheckingUtils.DoesExpressionResolveToType(config, expression, multiplicationExpression.Right, "int_base", ref errorMessage)) || !(typeCheckingUtils.DoesExpressionResolveToType(config, expression, multiplicationExpression.Left, "fixed_base", ref errorMessage) && typeCheckingUtils.DoesExpressionResolveToType(config, expression, multiplicationExpression.Right, "fixed_base", ref errorMessage))) {
                        errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot resolve addition expressions to the same type or addition expressions resolve to a type that is unable to be merged. " + errorMessage, FileName = expression.FileName, Entity = expression });
                        if (!config.ContinueOnError) {
                            return false;
                        }
                    }
                } else if (expression.GetType() == typeof(GrapeNameofExpression)) {
                    GrapeNameofExpression nameofExpression = expression as GrapeNameofExpression;
                    if (nameofExpression.Value.GetType() != typeof(GrapeMemberExpression)) {
                        errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot resolve expression to type, field or function.", FileName = expression.FileName, Entity = expression });
                        if (!config.ContinueOnError) {
                            return false;
                        }
                    }

                    string qualifiedId = nameofExpression.Value.ToString();
                    GrapeEntity valueEntity = (new List<GrapeEntity>(typeCheckingUtils.GetEntitiesForAccessExpression(config, nameofExpression.Value, expression, out errorMessage, false)))[0];
                    if (valueEntity == null) {
                        errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot find entity for expression '" + qualifiedId + "'. " + errorMessage, FileName = expression.FileName, Entity = expression });
                        if (!config.ContinueOnError) {
                            return false;
                        }
                    }

                    GrapeClass c = expression.GetLogicalParentOfEntityType<GrapeClass>();
                    GrapeModifier.GrapeModifierType modifiers = c.GetAppropriateModifiersForEntityAccess(config, valueEntity);
                    GrapeModifier.GrapeModifierType potentialModifiers = valueEntity.GetPotentialModifiersOfEntity();
                    bool invalidModifiers = false;
                    if (modifiers != 0) {
                        if (potentialModifiers == 0) {
                            if (modifiers == GrapeModifier.GrapeModifierType.Public) {
                                invalidModifiers = false;
                            } else {
                                invalidModifiers = true;
                            }
                        } else {
                            if (modifiers != potentialModifiers) {
                                invalidModifiers = true;
                            }
                        }
                    } else {
                        invalidModifiers = true;
                    }

                    if (invalidModifiers) {
                        errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot access member '" + qualifiedId + "'.", FileName = expression.FileName, Entity = expression });
                        if (!config.ContinueOnError) {
                            return false;
                        }
                    }
                } else if (expression.GetType() == typeof(GrapeShiftExpression)) {
                    GrapeShiftExpression shiftExpression = expression as GrapeShiftExpression;
                    if (!(typeCheckingUtils.DoesExpressionResolveToType(config, expression, shiftExpression.Left, "int_base", ref errorMessage) && typeCheckingUtils.DoesExpressionResolveToType(config, expression, shiftExpression.Right, "int_base", ref errorMessage))) {
                        errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot resolve shift expressions to the same type or addition expressions resolve to a type that is unable to be merged. " + errorMessage, FileName = expression.FileName, Entity = expression });
                        if (!config.ContinueOnError) {
                            return false;
                        }
                    }
                } else if (expression.GetType() == typeof(GrapeTypecastExpression)) {
                    GrapeTypecastExpression typecastExpression = expression as GrapeTypecastExpression;
                    if (typeCheckingUtils.DoesExpressionResolveToType(config, typecastExpression, typecastExpression.Value, "text_base")) {
                        errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot cast from type 'text_base'.", FileName = expression.FileName, Entity = expression });
                        if (!config.ContinueOnError) {
                            return false;
                        }
                    }

                    return typeCheckingUtils.DoesExpressionResolveToType(config, expression, typecastExpression.Value, typecastExpression.TypeName);
                } else if (expression.GetType() == typeof(GrapeUnaryExpression)) {
                    GrapeUnaryExpression unaryExpression = expression as GrapeUnaryExpression;
                    if (unaryExpression.Type == GrapeUnaryExpression.GrapeUnaryExpressionType.Not) {
                        if (!typeCheckingUtils.DoesExpressionResolveToType(config, expression, unaryExpression.Value, "bool_base", ref errorMessage)) {
                            errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot resolve expression to the type 'bool_base'. " + errorMessage, FileName = expression.FileName, Entity = expression });
                            if (!config.ContinueOnError) {
                                return false;
                            }
                        }
                    } else if (!(typeCheckingUtils.DoesExpressionResolveToType(config, expression, unaryExpression.Value, "int_base", ref errorMessage))) {
                        errorSink.AddError(new GrapeErrorSink.Error { Description = "Cannot resolve expression to the type 'int_base'. " + errorMessage, FileName = expression.FileName, Entity = expression });
                        if (!config.ContinueOnError) {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
예제 #4
0
        public IEnumerable<GrapeMethod> GetMethodsWithNameFromImportedPackagesInFile(GrapeCodeGeneratorConfiguration config, string methodName, string fileName, GrapeClass c)
        {
            PopulatePackageFileNames(config.Ast);
            List<string> importedPackageFiles = new List<string>();
            IEnumerable<GrapeEntity> importDeclarationsInFile = GetEntitiesOfTypeInFile(config.Ast, fileName, typeof(GrapeImportDeclaration));
            foreach (GrapeImportDeclaration importDeclaration in importDeclarationsInFile) {
                foreach (KeyValuePair<string, List<string>> pair in packageFileNames) {
                    if (pair.Key == importDeclaration.PackageName) {
                        foreach (string packageFileName in pair.Value) {
                            importedPackageFiles.Add(packageFileName);
                        }
                    }
                }
            }

            IList<string> segmentsInVariableName = GetSegmentsInQualifiedId(methodName, true);
            string actualFunctionName = segmentsInVariableName[segmentsInVariableName.Count - 1];
            string actualQualifiedId = "";
            for (int i = 0; i < segmentsInVariableName.Count - 1; i++) {
                actualQualifiedId += segmentsInVariableName[i] + ".";
            }

            actualQualifiedId = actualQualifiedId.Trim('.');
            if (actualQualifiedId == "this") {
                List<GrapeMethod> l = new List<GrapeMethod>();
                foreach (GrapeMethod m in GetEntitiesOfTypeInFile(config.Ast, fileName, typeof(GrapeMethod))) {
                    if (m.Name == actualFunctionName && m.GetLogicalParentOfEntityType<GrapeClass>() == c) {
                        l.Add(m);
                    }
                }

                return l;
            } else if (actualQualifiedId == "base") {
                List<GrapeMethod> l = new List<GrapeMethod>();
                foreach (GrapeMethod m in GetEntitiesOfTypeInFile(config.Ast, fileName, typeof(GrapeMethod))) {
                    if (m.Name == actualFunctionName && m.GetLogicalParentOfEntityType<GrapeClass>() == GetClassWithNameFromImportedPackagesInFile(config.Ast, typeCheckingUtils.GetTypeNameForTypeAccessExpression(config, c.Inherits), fileName)) {
                        l.Add(m);
                    }
                }

                return l;
            }

            IEnumerable<GrapeEntity> packagesInFile = GetEntitiesOfTypeInFile(config.Ast, fileName, typeof(GrapePackageDeclaration));
            foreach (GrapePackageDeclaration packageDeclaration in packagesInFile) {
                foreach (KeyValuePair<string, List<string>> pair in packageFileNames) {
                    if (pair.Key == packageDeclaration.PackageName) {
                        IEnumerable<string> otherPackagesInPackage = GetOtherPackagesInPackageName(packageDeclaration.PackageName);
                        foreach (string otherPackage in otherPackagesInPackage) {
                            foreach (KeyValuePair<string, List<string>> childPair in packageFileNames) {
                                if (childPair.Key == otherPackage) {
                                    importedPackageFiles.AddRange(childPair.Value);
                                }
                            }
                        }

                        importedPackageFiles.AddRange(pair.Value);
                    }
                }
            }

            List<GrapeMethod> list = new List<GrapeMethod>();
            foreach (string importedPackageFile in importedPackageFiles) {
                IEnumerable<GrapeEntity> methods = GetEntitiesOfTypeInFile(config.Ast, importedPackageFile, typeof(GrapeMethod));
                foreach (GrapeMethod m in methods) {
                    if (m.Name == actualFunctionName && (m.GetLogicalParentOfEntityType<GrapeClass>() == c || c.IsClassInInheritanceTree(config, m.GetLogicalParentOfEntityType<GrapeClass>()))) {
                        list.Add(m);
                    }
                }
            }

            IEnumerable<GrapeEntity> packages = GetEntitiesOfType(config.Ast, typeof(GrapePackageDeclaration));
            IEnumerable<GrapeEntity> allMethods = GetEntitiesOfType(config.Ast, typeof(GrapeMethod));
            foreach (GrapePackageDeclaration packageDeclaration in packages) {
                if (packageDeclaration.PackageName == actualQualifiedId) {
                    foreach (GrapeMethod m in allMethods) {
                        if (m.Name == actualFunctionName && (m.GetLogicalParentOfEntityType<GrapeClass>() == c || c.IsClassInInheritanceTree(config, m.GetLogicalParentOfEntityType<GrapeClass>()))) {
                            list.Add(m);
                        }
                    }
                }
            }

            if (list.Count > 1) {
                GrapeClass mostTopLevelClassInInheritanceTree = c;
                foreach (GrapeMethod method in list) {
                    GrapeClass functionClass = method.GetLogicalParentOfEntityType<GrapeClass>();
                    if (!mostTopLevelClassInInheritanceTree.IsClassInInheritanceTree(config, functionClass)) {
                        mostTopLevelClassInInheritanceTree = functionClass;
                    }
                }

                List<GrapeMethod> methodsToRemove = new List<GrapeMethod>();
                foreach (GrapeMethod method in list) {
                    if (method.GetLogicalParentOfEntityType<GrapeClass>() != mostTopLevelClassInInheritanceTree) {
                        methodsToRemove.Add(method);
                    }
                }

                methodsToRemove.ForEach(f => list.Remove(f));
            }

            return list;
        }
        public bool DoesExpressionResolveToType(GrapeCodeGeneratorConfiguration config, GrapeEntity parent, GrapeExpression expression, string typeName, ref string errorMessage)
        {
            if (parent == null) {
                throw new ArgumentNullException("parent");
            }

            if (expression is GrapeLiteralExpression) {
                if (typeName == literalTypes[((GrapeLiteralExpression)expression).Type]) {
                    return true;
                } else {
                    GrapeClass c = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, typeName, expression.FileName);
                    if (c != null && c.IsClassInInheritanceTree(config, astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, literalTypes[((GrapeLiteralExpression)expression).Type], expression.FileName))) {
                        return true;
                    }
                }

                return false;
            } else if (expression is GrapeConditionalExpression) {
                GrapeConditionalExpression conditionalExpression = expression as GrapeConditionalExpression;
                if (conditionalExpression.Type == GrapeConditionalExpression.GrapeConditionalExpressionType.BinaryAnd || conditionalExpression.Type == GrapeConditionalExpression.GrapeConditionalExpressionType.BinaryOr) {
                    return DoesExpressionResolveToType(config, parent, conditionalExpression.Left, "int_base", ref errorMessage) && DoesExpressionResolveToType(config, parent, conditionalExpression.Right, "int_base", ref errorMessage);
                }

                string leftType = GetTypeNameForTypeAccessExpression(config, conditionalExpression.Left, ref errorMessage);
                string rightType = GetTypeNameForTypeAccessExpression(config, conditionalExpression.Right, ref errorMessage);
                if (errorMessage != "") {
                    return false;
                }

                bool result = leftType == rightType;
                if (!result) {
                    GrapeClass left = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, leftType, parent.FileName);
                    GrapeClass right = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, rightType, parent.FileName);
                    if (left != null && right != null) {
                        if (left.IsClassInInheritanceTree(config, right)) {
                            return true;
                        }
                    }
                }

                if (!result) {
                    errorMessage = "Cannot resolve left and right expressions to the same type. The resolved left type is '" + leftType + "' and the resolved right type is '" + rightType + "'.";
                }

                return result;
            } else if (expression is GrapeMemberExpression) {
                GrapeEntity entity = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, expression as GrapeMemberExpression, parent, out errorMessage)))[0];
                if (entity != null) {
                    GrapeClass type = null;
                    if (entity is GrapeVariable) {
                        type = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetCorrectNativeTypeName(GetTypeNameForTypeAccessExpression(config, ((GrapeVariable)entity).Type, ref errorMessage)), parent.FileName);
                    } else if (entity is GrapeMethod) {
                        type = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetCorrectNativeTypeName(GetTypeNameForTypeAccessExpression(config, ((GrapeMethod)entity).ReturnType, ref errorMessage)), parent.FileName);
                    } else if (entity is GrapeClass) {
                        type = entity as GrapeClass;
                    }

                    if (type != null) {
                        return type.Name == GetCorrectNativeTypeName(typeName) || IsTypeInClassInheritanceTree(config, typeName, type);
                    }
                } else {
                    if (expression.GetType() == typeof(GrapeMemberExpression)) {
                        string qualifiedId = ((GrapeMemberExpression)expression).GetAccessExpressionQualifiedId();
                        foreach (GalaxyConstantAttribute constant in GalaxyNativeInterfaceAggregator.Constants) {
                            if (constant.Name == qualifiedId) {
                                return GetCorrectNativeTypeName(constant.Type) == GetCorrectNativeTypeName(typeName);
                            }
                        }
                    } else if (expression.GetType() == typeof(GrapeCallExpression)) {
                        GrapeCallExpression callExpression = expression as GrapeCallExpression;
                        GrapeAccessExpression accessExpression = callExpression.GetAccessExpressionInAccessExpression();
                        string qualifiedId = accessExpression.GetAccessExpressionQualifiedId();
                        foreach (GalaxyFunctionAttribute function in GalaxyNativeInterfaceAggregator.Functions) {
                            if (function.Name == qualifiedId) {
                                if (!IsSignatureValid(config, function, callExpression, out errorMessage)) {
                                    return false;
                                }

                                return GetCorrectNativeTypeName(function.Type) == GetCorrectNativeTypeName(typeName);
                            }
                        }
                    }
                }
            } else if (expression is GrapeNameofExpression) {
                GrapeNameofExpression nameofExpression = expression as GrapeNameofExpression;
                if (nameofExpression.Value.GetType() != typeof(GrapeMemberExpression)) {
                    errorMessage = "Cannot resolve expression to type, field or method.";
                    if (!config.ContinueOnError) {
                        return false;
                    }
                }

                string qualifiedId = nameofExpression.Value.ToString();
                GrapeEntity valueEntity = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, nameofExpression.Value, expression, out errorMessage, false)))[0];
                if (valueEntity == null) {
                    errorMessage = "Cannot find entity for expression '" + qualifiedId + "'. " + errorMessage;
                    if (!config.ContinueOnError) {
                        return false;
                    }
                }

                GrapeClass c = expression.GetLogicalParentOfEntityType<GrapeClass>();
                GrapeModifier.GrapeModifierType modifiers = c.GetAppropriateModifiersForEntityAccess(config, valueEntity);
                GrapeModifier.GrapeModifierType potentialModifiers = valueEntity.GetPotentialModifiersOfEntity();
                bool invalidModifiers = false;
                if (modifiers != 0) {
                    if (potentialModifiers == 0) {
                        if (modifiers == GrapeModifier.GrapeModifierType.Public) {
                            invalidModifiers = false;
                        } else {
                            invalidModifiers = true;
                        }
                    } else {
                        if (modifiers != potentialModifiers) {
                            invalidModifiers = true;
                        }
                    }
                } else {
                    invalidModifiers = true;
                }

                if (invalidModifiers) {
                    errorMessage = "Cannot access member '" + qualifiedId + "'.";
                    if (!config.ContinueOnError) {
                        return false;
                    }
                }

                return typeName == "string_base";
            } else if (expression is GrapeAddExpression) {
                GrapeAddExpression addExpression = expression as GrapeAddExpression;
                string leftType = GetTypeNameForTypeAccessExpression(config, addExpression.Left, ref errorMessage);
                string rightType = GetTypeNameForTypeAccessExpression(config, addExpression.Right, ref errorMessage);
                if (errorMessage != "") {
                    return false;
                }

                return leftType == rightType;
            } else if (expression is GrapeMultiplicationExpression) {
                GrapeMultiplicationExpression multiplicationExpression = expression as GrapeMultiplicationExpression;
                string leftType = GetTypeNameForTypeAccessExpression(config, multiplicationExpression.Left, ref errorMessage);
                string rightType = GetTypeNameForTypeAccessExpression(config, multiplicationExpression.Right, ref errorMessage);
                if (errorMessage != "") {
                    return false;
                }

                return leftType == rightType;
            } else if (expression is GrapeShiftExpression) {
                GrapeShiftExpression shiftExpression = expression as GrapeShiftExpression;
                string leftType = GetTypeNameForTypeAccessExpression(config, shiftExpression.Left, ref errorMessage);
                string rightType = GetTypeNameForTypeAccessExpression(config, shiftExpression.Right, ref errorMessage);
                if (errorMessage != "") {
                    return false;
                }

                return leftType == rightType;
            } else if (expression is GrapeTypecastExpression) {
                GrapeTypecastExpression typecastExpression = expression as GrapeTypecastExpression;
                if (DoesExpressionResolveToType(config, typecastExpression, typecastExpression.Value, "text_base")) {
                    errorMessage = "Cannot cast from type 'text_base'.";
                    return false;
                }

                return DoesExpressionResolveToType(config, parent, typecastExpression.TypeName, typeName, ref errorMessage);
            } else if (expression is GrapeUnaryExpression) {
                GrapeUnaryExpression unaryExpression = expression as GrapeUnaryExpression;
                return DoesExpressionResolveToType(config, parent, unaryExpression.Value, typeName, ref errorMessage);
            }

            return false;
        }
 public bool DoesExpressionResolveToType(GrapeCodeGeneratorConfiguration config, GrapeEntity parent, GrapeExpression expression, string typeName)
 {
     string dummyMessage = "";
     return DoesExpressionResolveToType(config, parent, expression, typeName, ref dummyMessage);
 }
 public string GetTypeNameForTypeAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeExpression expression)
 {
     string dummyMessage = "";
     return GetTypeNameForTypeAccessExpression(config, expression, ref dummyMessage);
 }
 public string GetTypeNameForTypeAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeType type)
 {
     // left for compat
     string dummyMessage = "";
     return GetTypeNameForTypeAccessExpression(config, type, ref dummyMessage);
 }
 public bool DoesExpressionResolveToType(GrapeCodeGeneratorConfiguration config, GrapeEntity parent, GrapeExpression expression, GrapeType type)
 {
     // left for compat
     string dummyMessage = "";
     return DoesExpressionResolveToType(config, parent, expression, type, ref dummyMessage);
 }
 public bool DoesExpressionResolveToType(GrapeCodeGeneratorConfiguration config, GrapeEntity parent, GrapeType expression, GrapeType type)
 {
     // left for compat
     return expression.ToString() == type.ToString();
 }
        public IEnumerable<GrapeEntity> GetEntitiesForAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeAccessExpression accessExpression, GrapeEntity parent, out string errorMessage, bool detectMethodsUsedAsTypesOrVars)
        {
            errorMessage = "";
            string memberExpressionQualifiedId = accessExpression.GetAccessExpressionQualifiedId();
            if (memberExpressionQualifiedId == "this") {
                if ((accessExpression.GetType() != typeof(GrapeMemberExpression) && accessExpression.GetType() != typeof(GrapeSetExpression)) || (parent is GrapeExpression && parent.GetType() != typeof(GrapeMemberExpression) && parent.GetType() != typeof(GrapeSetExpression))) {
                    errorMessage = "Cannot access this class through a statement expression.";
                    return new GrapeEntity[] { null };
                }

                GrapeClass thisClass = parent.GetLogicalParentOfEntityType<GrapeClass>();
                if (thisClass != null) {
                    return new GrapeEntity[] { thisClass };
                }

                return new GrapeEntity[] { null };
            } else if (memberExpressionQualifiedId == "base") {
                if ((accessExpression.GetType() != typeof(GrapeMemberExpression) && accessExpression.GetType() != typeof(GrapeSetExpression)) || (parent is GrapeExpression && parent.GetType() != typeof(GrapeMemberExpression) && parent.GetType() != typeof(GrapeSetExpression))) {
                    errorMessage = "Cannot access base class through a statement expression.";
                    return new GrapeEntity[] { null };
                }

                GrapeClass thisClass = parent.GetLogicalParentOfEntityType<GrapeClass>();
                if (thisClass != null && thisClass.Inherits != null) {
                    GrapeClass baseClass = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetTypeNameForTypeAccessExpression(config, thisClass.Inherits, ref errorMessage), parent.FileName);
                    return new GrapeEntity[] { baseClass };
                }

                return new GrapeEntity[] { null };
            } else if (accessExpression is GrapeCallExpression) {
                GrapeAccessExpression identifierExpression = accessExpression.GetAccessExpressionInAccessExpression();
                GrapeEntity entity = null;
                GrapeEntity lastParent = null;
                GrapeEntity lastLastParent = null;
                GrapeEntity lastMemberAccess = null;
                GrapeAccessExpression currentExpression = identifierExpression;
                bool lastClassAccessWasThisOrBaseAccess = false;
                bool shouldBeStatic = false;
                bool staticnessMatters = false;
                while (currentExpression != null) {
                    //lastParent = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, currentExpression, lastParent == null ? accessExpression as GrapeEntity : lastParent.GetLogicalParentOfEntityType<GrapeClass>(), out errorMessage)))[0];
                    if (currentExpression is GrapeCallExpression) {
                        List<GrapeEntity> list = (new List<GrapeEntity>(astUtils.GetMethodsWithNameFromImportedPackagesInFile(config, currentExpression.GetAccessExpressionQualifiedId(), currentExpression.FileName, currentExpression.GetLogicalParentOfEntityType<GrapeClass>())));
                        if (list.Count > 0) {
                            lastParent = list[0];
                        }
                    } else {
                        lastParent = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, currentExpression, lastParent == null ? accessExpression as GrapeEntity : lastParent.GetLogicalParentOfEntityType<GrapeClass>(), out errorMessage)))[0];
                    }

                    if (lastParent == null) {
                        break;
                    }

                    if (lastParent is GrapeMethod && !(currentExpression is GrapeCallExpression) && !(accessExpression is GrapeCallExpression) && !(parent is GrapeCallExpression) && detectMethodsUsedAsTypesOrVars) {
                        errorMessage = "Cannot use method '" + currentExpression.GetAccessExpressionQualifiedId() + "' as a variable or type.";
                        return new GrapeEntity[] { null };
                    }

                    if (lastLastParent != null) {
                        if (lastMemberAccess != null) {
                            GrapeClass c = null;
                            if (lastMemberAccess is GrapeVariable) {
                                c = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeVariable)lastMemberAccess).Type, lastMemberAccess, out errorMessage)))[0] as GrapeClass;
                            } else if (lastMemberAccess is GrapeMethod) {
                                c = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeMethod)lastMemberAccess).ReturnType, lastMemberAccess, out errorMessage)))[0] as GrapeClass;
                            }

                            if (c != null) {
                                lastLastParent = c;
                                shouldBeStatic = false;
                                staticnessMatters = true;
                            }

                            lastMemberAccess = null;
                        } else if (lastLastParent is GrapeClass) {
                            shouldBeStatic = !lastClassAccessWasThisOrBaseAccess && !(lastParent is GrapeClass);
                            staticnessMatters = true;
                        } else if (lastLastParent is GrapeField) {
                            GrapeModifier.GrapeModifierType variableModifiers = ((GrapeField)lastLastParent).Modifiers;
                            shouldBeStatic = variableModifiers.Contains(GrapeModifier.GrapeModifierType.Static);
                            lastMemberAccess = lastLastParent as GrapeField;
                            staticnessMatters = true;
                        } else if (lastLastParent is GrapeVariable) {
                            shouldBeStatic = false;
                            staticnessMatters = true;
                            lastMemberAccess = lastLastParent as GrapeVariable;
                        } else if (lastLastParent is GrapeMethod) {
                            GrapeModifier.GrapeModifierType methodModifiers = ((GrapeMethod)lastLastParent).Modifiers;
                            shouldBeStatic = methodModifiers.Contains(GrapeModifier.GrapeModifierType.Static);
                            staticnessMatters = true;
                            lastMemberAccess = lastLastParent as GrapeMethod;
                        }
                    }

                    GrapeModifier.GrapeModifierType modifiers = lastParent.GetPotentialModifiersOfEntity();
                    if (modifiers != 0 && staticnessMatters) {
                        if (shouldBeStatic && !modifiers.Contains(GrapeModifier.GrapeModifierType.Static)) {
                            errorMessage = "Cannot access instance member when the context implies that a static member should be accessed. The expression is '" + identifierExpression.GetAccessExpressionQualifiedId() + "'.";
                            return new GrapeEntity[] { null };
                        } else if (!shouldBeStatic && modifiers.Contains(GrapeModifier.GrapeModifierType.Static)) {
                            errorMessage = "Cannot access static member when the context implies that an instance member should be accessed. The expression is '" + identifierExpression.GetAccessExpressionQualifiedId() + "'.";
                            return new GrapeEntity[] { null };
                        }
                    }

                    lastLastParent = lastParent;
                    if (lastLastParent is GrapeVariable || lastLastParent is GrapeMethod) {
                        lastMemberAccess = lastLastParent;
                    }

                    lastClassAccessWasThisOrBaseAccess = currentExpression.GetAccessExpressionQualifiedId() == "this" || currentExpression.GetAccessExpressionQualifiedId() == "base";
                    currentExpression = currentExpression.Next;
                }

                entity = lastParent;
                if (entity != null) {
                    GrapeMethod method = entity as GrapeMethod;
                    if (method != null && accessExpression is GrapeCallExpression && !accessExpressionValidator.ValidateMethodSignatureAndOverloads(((GrapeCallExpression)accessExpression), method, GrapeModifier.GrapeModifierType.Public, ref errorMessage)) {
                        return new GrapeEntity[] { entity };
                    }

                    GrapeAccessExpression memberExpressionWithNext = accessExpression.Next == null ? identifierExpression : accessExpression;
                    if (memberExpressionWithNext.Next != null) {
                        GrapeEntity newParent = null;
                        if (entity is GrapeClass) {
                            newParent = entity as GrapeClass;
                        } else if (entity is GrapeMethod) {
                            newParent = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeMethod)entity).ReturnType, parent, out errorMessage)))[0];
                        } else if (entity is GrapeVariable) {
                            newParent = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeVariable)entity).Type, parent, out errorMessage)))[0];
                        }

                        return GetEntitiesForAccessExpression(config, memberExpressionWithNext.Next, newParent, out errorMessage);
                    }

                    return new GrapeEntity[] { entity };
                }
            } else if (accessExpression is GrapeMemberExpression) {
                GrapeEntity foundEntity = null;
                GrapeEntity lastParent = null;
                GrapeEntity lastEntity = null;
                GrapeEntity lastLastEntity = null;
                GrapeEntity lastMemberAccess = null;
                GrapeAccessExpression currentExpression = accessExpression;
                IEnumerable<GrapeEntity> members = null;
                IEnumerable<GrapeEntity> classes = null;
                bool lastClassAccessWasThisOrBaseAccess = false;
                bool shouldBeStatic = false;
                bool staticnessMatters = false;
                while (currentExpression != null) {
                    string qualifiedId = currentExpression.GetAccessExpressionQualifiedId();
                    IList<GrapeEntity> currentMembers = new List<GrapeEntity>(GetMembersForExpression(config, qualifiedId, lastParent == null ? parent : lastParent));
                    IList<GrapeEntity> currentClasses = new List<GrapeEntity>(GetClassesForExpression(config, qualifiedId, lastParent == null ? parent : lastParent));
                    lastParent = currentClasses.Count() == 1 && currentClasses[0] != null ? currentClasses[0] : currentMembers.Count() > 0 ? currentMembers[0] is GrapeVariable ? astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetTypeNameForTypeAccessExpression(config, ((GrapeVariable)currentMembers[0]).Type), parent.FileName) : currentMembers[0] is GrapeMethod ? astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetTypeNameForTypeAccessExpression(config, ((GrapeMethod)currentMembers[0]).ReturnType), parent.FileName) : null : null;
                    lastEntity = currentClasses.Count() == 1 && currentClasses[0] != null ? currentClasses[0] : currentMembers.Count() > 0 ? currentMembers[0] : null;
                    if (lastParent == null) {
                        members = null;
                        classes = null;
                        break;
                    }

                    if (lastEntity is GrapeMethod && !(currentExpression is GrapeCallExpression) && !(accessExpression is GrapeCallExpression) && !(parent is GrapeCallExpression) && detectMethodsUsedAsTypesOrVars) {
                        errorMessage = "Cannot use method '" + qualifiedId + "' as a variable or type.";
                        return new GrapeEntity[] { null };
                    }

                    if (lastLastEntity != null) {
                        if (lastMemberAccess != null) {
                            GrapeClass c = null;
                            if (lastMemberAccess is GrapeVariable) {
                                c = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeVariable)lastMemberAccess).Type, lastMemberAccess, out errorMessage)))[0] as GrapeClass;
                            } else if (lastMemberAccess is GrapeMethod) {
                                c = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeMethod)lastMemberAccess).ReturnType, lastMemberAccess, out errorMessage)))[0] as GrapeClass;
                            }

                            if (c != null) {
                                lastLastEntity = c;
                                shouldBeStatic = false;
                                staticnessMatters = true;
                            }

                            lastMemberAccess = null;
                        } else if (lastLastEntity is GrapeClass) {
                            shouldBeStatic = !lastClassAccessWasThisOrBaseAccess && !(lastEntity is GrapeClass);
                            staticnessMatters = true;
                        } else if (lastLastEntity is GrapeField) {
                            GrapeModifier.GrapeModifierType variableModifiers = ((GrapeField)lastLastEntity).Modifiers;
                            shouldBeStatic = variableModifiers.Contains(GrapeModifier.GrapeModifierType.Static);
                            staticnessMatters = true;
                            lastMemberAccess = lastLastEntity as GrapeField;
                        } else if (lastLastEntity is GrapeVariable) {
                            shouldBeStatic = false;
                            staticnessMatters = true;
                            lastMemberAccess = lastLastEntity as GrapeVariable;
                        } else if (lastLastEntity is GrapeMethod) {
                            GrapeModifier.GrapeModifierType methodModifiers = ((GrapeMethod)lastLastEntity).Modifiers;
                            shouldBeStatic = methodModifiers.Contains(GrapeModifier.GrapeModifierType.Static);
                            staticnessMatters = true;
                            lastMemberAccess = lastLastEntity as GrapeMethod;
                        }
                    }

                    GrapeModifier.GrapeModifierType modifiers = lastEntity.GetPotentialModifiersOfEntity();
                    if (modifiers != 0 && staticnessMatters) {
                        if (shouldBeStatic && !modifiers.Contains(GrapeModifier.GrapeModifierType.Static)) {
                            errorMessage = "Cannot access instance member when the context implies that a static member should be accessed. The expression is '" + accessExpression.GetAccessExpressionQualifiedId() + "'.";
                            return new GrapeEntity[] { null };
                        } else if (!shouldBeStatic && modifiers.Contains(GrapeModifier.GrapeModifierType.Static)) {
                            errorMessage = "Cannot access static member when the context implies that an instance member should be accessed. The expression is '" + accessExpression.GetAccessExpressionQualifiedId() + "'.";
                            return new GrapeEntity[] { null };
                        }
                    }

                    lastLastEntity = lastEntity;
                    if (lastLastEntity is GrapeVariable || lastLastEntity is GrapeMethod) {
                        lastMemberAccess = lastLastEntity;
                    }

                    lastClassAccessWasThisOrBaseAccess = currentExpression.GetAccessExpressionQualifiedId() == "this" || currentExpression.GetAccessExpressionQualifiedId() == "base";
                    members = currentMembers;
                    classes = currentClasses;
                    currentExpression = currentExpression.Next;
                }

                foundEntity = lastParent;
                List<GrapeEntity> entities = new List<GrapeEntity>();
                if (members != null) {
                    entities.AddRange(members);
                    if (classes != null && classes.Count() > 0) {
                        List<GrapeEntity> membersToRemove = new List<GrapeEntity>();
                        foreach (GrapeClass c in classes) {
                            if (c != null) {
                                foreach (GrapeEntity member in members) {
                                    if (member is GrapeMethod && ((GrapeMethod)member).Name == c.Name) {
                                        membersToRemove.Add(member);
                                    }
                                }
                            }
                        }

                        membersToRemove.ForEach(m => entities.Remove(m));
                    }
                }

                if (classes != null) {
                    entities.AddRange(classes);
                }

                if (entities.Count == 0) {
                    if (errorMessage == "") {
                        errorMessage = "Cannot find variable, field, type or method with name '" + memberExpressionQualifiedId + "'.";
                    }

                    return new GrapeEntity[] { null };
                }

                GrapeMethod method = null;
                foreach (GrapeEntity entity in entities) {
                    if (entity is GrapeMethod) {
                        method = entity as GrapeMethod;
                        break;
                    }
                }

                if (method != null) {
                    GrapeAccessExpression currentMemberExpression = accessExpression;
                    GrapeCallExpression callExpression = null;
                    while (currentMemberExpression != null) {
                        if (currentMemberExpression is GrapeCallExpression && ((GrapeCallExpression)currentMemberExpression).GetAccessExpressionQualifiedId() == method.Name) {
                            callExpression = currentMemberExpression as GrapeCallExpression;
                        }

                        currentMemberExpression = currentMemberExpression.Next;
                    }

                    if (callExpression != null && !accessExpressionValidator.ValidateMethodSignatureAndOverloads(callExpression, method, GrapeModifier.GrapeModifierType.Public, ref errorMessage)) {
                        return entities;
                    }
                }

                return entities;
            }

            return new GrapeEntity[] { null };
        }
 public IEnumerable<GrapeEntity> GetEntitiesForAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeType type, GrapeEntity parent, out string errorMessage, bool detectMethodsUsedAsTypesOrVars)
 {
     // left for compat
     errorMessage = "";
     return GetClassesForExpression(config, type.ToString(), parent);
 }
        public IEnumerable<GrapeEntity> GetClassesForExpression(GrapeCodeGeneratorConfiguration config, string className, GrapeEntity parent)
        {
            List<GrapeEntity> list = new List<GrapeEntity>();
            if (className == "this") {
                GrapeClass c = parent.GetLogicalParentOfEntityType<GrapeClass>();
                list.Add(c);
            } else if (className == "base") {
                GrapeClass c = parent.GetLogicalParentOfEntityType<GrapeClass>();
                if (c.Inherits == null) {
                    list.Add(null);
                } else {
                    GrapeClass inheritingClass = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetTypeNameForTypeAccessExpression(config, c.Inherits), parent.FileName);
                    list.Add(inheritingClass);
                }
            } else {
                list.Add(astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetCorrectNativeTypeName(className), parent.FileName));
            }

            return list;
        }
 public bool DoesTypeExist(GrapeCodeGeneratorConfiguration config, GrapeType type, string fileName)
 {
     string dummyMessage = "";
     return DoesTypeExist(config, GetTypeNameForTypeAccessExpression(config, type, ref dummyMessage), fileName);
 }
 public bool DoesExpressionResolveToType(GrapeCodeGeneratorConfiguration config, GrapeEntity parent, GrapeType expression, string typeName, ref string errorMessage)
 {
     // left for compat
     return expression.ToString() == typeName;
 }
        public List<GrapeMethod> GetMethodsWithSignature(GrapeCodeGeneratorConfiguration config, List<GrapeMethod> methods, GrapeModifier.GrapeModifierType modifiers, string name, GrapeType returnType, List<GrapeVariable> parameters, ref string errorMessage)
        {
            List<GrapeMethod> foundMethods = new List<GrapeMethod>();
            string parameterErrorMessage = "";
            foreach (GrapeMethod method in methods) {
                if (method.Name == name && GetTypeNameForTypeAccessExpression(config, method.ReturnType) == GetTypeNameForTypeAccessExpression(config, returnType) && method.Parameters.Count == parameters.Count) {
                    if (modifiers != 0) {
                        bool shouldContinue = false;
                        if (modifiers != method.Modifiers) {
                            shouldContinue = true;
                        }

                        if (shouldContinue) {
                            continue;
                        }
                    }

                    int currentParameterIndex = 0;
                    bool validParameters = true;
                    foreach (GrapeVariable param in method.Parameters) {
                        GrapeVariable currentParameter = parameters[currentParameterIndex];
                        if (!DoesExpressionResolveToType(config, currentParameter, currentParameter.Type, param.Type, ref parameterErrorMessage)) {
                            validParameters = false;
                            if (parameterErrorMessage == "") {
                                parameterErrorMessage = "Cannot resolve parameter type '" + GetTypeNameForTypeAccessExpression(config, currentParameter.Type) + "' to type '" + GetTypeNameForTypeAccessExpression(config, param.Type) + "'.";
                            }

                            break;
                        }

                        currentParameterIndex++;
                    }

                    if (validParameters) {
                        foundMethods.Add(method);
                    }
                }
            }

            if (foundMethods.Count == 0) {
                errorMessage = "Cannot find method with signature '" + GetMethodSignatureString(config, name, returnType, parameters) + "'. " + parameterErrorMessage;
            }

            return foundMethods;
        }
 public IEnumerable<GrapeEntity> GetEntitiesForAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeSetExpression setExpression, GrapeEntity parent, out string errorMessage)
 {
     return GetEntitiesForAccessExpression(config, setExpression, parent, out errorMessage, true);
 }
 public string GetTypeNameForTypeAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeType type, ref string errorMessage)
 {
     // left for compat
     return type.ToString();
 }
 public IEnumerable<GrapeEntity> GetEntitiesForAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeSetExpression setExpression, GrapeEntity parent, out string errorMessage, bool detectMethodsUsedAsTypesOrVars)
 {
     return GetEntitiesForAccessExpression(config, setExpression.MemberAccess, parent, out errorMessage, true);
 }
        public string GetTypeNameForTypeAccessExpression(GrapeCodeGeneratorConfiguration config, GrapeExpression expression, ref string errorMessage)
        {
            if (expression is GrapeMemberExpression) {
                GrapeEntity entity = (new List<GrapeEntity>(GetEntitiesForAccessExpression(config, ((GrapeMemberExpression)expression), expression, out errorMessage)))[0];
                if (entity is GrapeVariable) {
                    return GetCorrectNativeTypeName(((GrapeVariable)entity).Type.ToString());
                } else if (entity is GrapeMethod) {
                    return GetCorrectNativeTypeName(((GrapeMethod)entity).ReturnType.ToString());
                } else if (entity is GrapeClass) {
                    return GetCorrectNativeTypeName((entity as GrapeClass).Name);
                } else if (entity == null) {
                    string qualifiedId = ((GrapeMemberExpression)expression).GetAccessExpressionQualifiedId();
                    foreach (GalaxyFunctionAttribute function in GalaxyNativeInterfaceAggregator.Functions) {
                        if (function.Name == qualifiedId) {
                            errorMessage = "";
                            return GetCorrectNativeTypeName(function.Type);
                        }
                    }

                    foreach (GalaxyConstantAttribute constant in GalaxyNativeInterfaceAggregator.Constants) {
                        if (constant.Name == qualifiedId) {
                            errorMessage = "";
                            return GetCorrectNativeTypeName(constant.Type);
                        }
                    }

                    foreach (Tuple<GalaxyTypeAttribute, GalaxyTypeDefaultValueAttribute> type in GalaxyNativeInterfaceAggregator.Types) {
                        if (type.Item1.NativeAlias == qualifiedId || type.Item1.TypeName == qualifiedId) {
                            errorMessage = "";
                            return GetCorrectNativeTypeName(type.Item1.NativeAlias);
                        }
                    }
                }

                return "";// GetCorrectNativeTypeName(((GrapeMemberExpression)expression).GetMemberExpressionQualifiedId());
            } else if (expression is GrapeLiteralExpression) {
                return literalTypes[((GrapeLiteralExpression)expression).Type];
            } else if (expression is GrapeAddExpression) {
                GrapeAddExpression addExpression = expression as GrapeAddExpression;
                string leftType = GetTypeNameForTypeAccessExpression(config, addExpression.Left, ref errorMessage);
                string rightType = GetTypeNameForTypeAccessExpression(config, addExpression.Right, ref errorMessage);
                if (leftType != rightType) {
                    errorMessage = "The left and right expressions do not resolve to the same type.";
                }

                return leftType;
            } else if (expression is GrapeMultiplicationExpression) {
                GrapeMultiplicationExpression multiplicationExpression = expression as GrapeMultiplicationExpression;
                string leftType = GetTypeNameForTypeAccessExpression(config, multiplicationExpression.Left, ref errorMessage);
                string rightType = GetTypeNameForTypeAccessExpression(config, multiplicationExpression.Right, ref errorMessage);
                if (leftType != rightType) {
                    errorMessage = "The left and right expressions do not resolve to the same type.";
                }

                return leftType;
            } else if (expression is GrapeShiftExpression) {
                GrapeShiftExpression shiftExpression = expression as GrapeShiftExpression;
                string leftType = GetTypeNameForTypeAccessExpression(config, shiftExpression.Left, ref errorMessage);
                string rightType = GetTypeNameForTypeAccessExpression(config, shiftExpression.Right, ref errorMessage);
                if (leftType != rightType) {
                    errorMessage = "The left and right expressions do not resolve to the same type.";
                }

                return leftType;
            } else if (expression is GrapeUnaryExpression) {
                GrapeUnaryExpression unaryExpression = expression as GrapeUnaryExpression;
                return GetTypeNameForTypeAccessExpression(config, unaryExpression.Value, ref errorMessage);
            }

            return "";
        }
 public IEnumerable<GrapeEntity> GetEntitiesForObjectCreationExpression(GrapeCodeGeneratorConfiguration config, GrapeObjectCreationExpression objectCreationExpression, GrapeEntity parent)
 {
     string dummyMessage = "";
     return GetEntitiesForObjectCreationExpression(config, objectCreationExpression, parent, out dummyMessage);
 }
        public bool IsSignatureValid(GrapeCodeGeneratorConfiguration config, GalaxyFunctionAttribute function, GrapeCallExpression callExpression, out string errorMessage)
        {
            errorMessage = "";
            string[] parameters = function.Params.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            if (parameters.Length != callExpression.Parameters.Count) {
                errorMessage = "Cannot find function with argument count '" + callExpression.Parameters.Count + "'.";
                return false;
            }

            int index = 0;
            foreach (string parameter in parameters) {
                string[] splitParam = parameter.Trim().Split(' ');
                if (splitParam.Length != 2) {
                    errorMessage = "The native interface function has malformed parameters.";
                    return false;
                }

                string type = GetCorrectNativeTypeName(splitParam[0]);
                string name = splitParam[1];
                GrapeExpression expression = callExpression.Parameters[index];
                if (!DoesExpressionResolveToType(config, expression, expression, type, ref errorMessage)) {
                    errorMessage = "Cannot resolve parameter expression to type '" + type + "'. " + errorMessage;
                    return false;
                }

                index++;
            }

            return true;
        }
 public bool DoesExpressionResolveToType(GrapeCodeGeneratorConfiguration config, GrapeEntity parent, GrapeExpression expression, GrapeType type, ref string errorMessage)
 {
     // left for compat
     return DoesExpressionResolveToType(config, parent, expression, type.ToString(), ref errorMessage);
 }
        public bool IsTypeInClassInheritanceTree(GrapeCodeGeneratorConfiguration config, string typeName, GrapeClass c)
        {
            typeName = GetCorrectNativeTypeName(typeName);
            if (typeName == c.Name) {
                return true;
            }

            if (c == null) {
                return false;
            }

            if (c.Inherits != null) {
                string inheritsTypeName = c.Inherits.ToString();
                if (inheritsTypeName == typeName) {
                    return true;
                }

                return IsTypeInClassInheritanceTree(config, typeName, astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, inheritsTypeName, c.FileName));
            }

            return false;
        }
        public IEnumerable<GrapeEntity> GetEntitiesForObjectCreationExpression(GrapeCodeGeneratorConfiguration config, GrapeObjectCreationExpression objectCreationExpression, GrapeEntity parent, out string errorMessage)
        {
            errorMessage = "";
            GrapeClass c = astUtils.GetClassWithNameFromImportedPackagesInFile(config.Ast, GetTypeNameForTypeAccessExpression(config, objectCreationExpression.ClassName), objectCreationExpression.FileName);
            if (c != null) {
                List<GrapeMethod> constructors = c.GetConstructors();
                if (constructors.Count == 0) {
                    GrapeMethod method = new GrapeConstructor(new GrapeList<GrapeModifier>(new GrapePublicModifier()), new GrapeIdentifier(c.Name), new GrapeList<GrapeParameter>(), new GrapeList<GrapeStatement>());
                    method.Parent = c;
                    return new GrapeEntity[] { method };
                } else {
                    errorMessage = "";
                    GrapeModifier.GrapeModifierType modifiers = objectCreationExpression.GetLogicalParentOfEntityType<GrapeClass>().GetAppropriateModifiersForEntityAccess(config, constructors[0]);
                    List<GrapeMethod> methodsWithSignature = GetMethodsWithSignature(config, constructors, modifiers, c.Name, new GrapeSimpleType(new GrapeList<GrapeIdentifier>(new GrapeIdentifier(c.Name))), new List<GrapeExpression>(objectCreationExpression.Parameters), ref errorMessage);
                    if (methodsWithSignature.Count > 1) {
                        errorMessage = "Multiple methods with signature '" + GetMethodSignatureString(config, c.Name, new GrapeSimpleType(new GrapeList<GrapeIdentifier>(new GrapeIdentifier(c.Name))), new List<GrapeExpression>(objectCreationExpression.Parameters)) + "' found.";
                        return new GrapeEntity[] { null };
                    }

                    if (methodsWithSignature.Count == 0) {
                        return new GrapeEntity[] { null };
                    }

                    return methodsWithSignature;
                }
            }

            return new GrapeEntity[] { null };
        }
예제 #26
0
        public IEnumerable<GrapeVariable> GetVariablesWithNameFromImportedPackagesInFile(GrapeCodeGeneratorConfiguration config, string variableName, string fileName, GrapeEntity e)
        {
            PopulatePackageFileNames(config.Ast);
            List<string> importedPackageFiles = new List<string>();
            IEnumerable<GrapeEntity> importDeclarationsInFile = GetEntitiesOfTypeInFile(config.Ast, fileName, typeof(GrapeImportDeclaration));
            foreach (GrapeImportDeclaration importDeclaration in importDeclarationsInFile) {
                foreach (KeyValuePair<string, List<string>> pair in packageFileNames) {
                    if (pair.Key == importDeclaration.PackageName) {
                        foreach (string packageFileName in pair.Value) {
                            importedPackageFiles.Add(packageFileName);
                        }
                    }
                }
            }

            IList<string> segmentsInVariableName = GetSegmentsInQualifiedId(variableName, true);
            string actualVariableName = segmentsInVariableName[segmentsInVariableName.Count - 1];
            string actualQualifiedId = "";
            for (int i = 0; i < segmentsInVariableName.Count - 1; i++) {
                actualQualifiedId += segmentsInVariableName[i] + ".";
            }

            actualQualifiedId = actualQualifiedId.Trim('.');
            GrapeClass c = e as GrapeClass;
            if (actualQualifiedId == "this" && c != null) {
                List<GrapeVariable> l = new List<GrapeVariable>();
                foreach (GrapeVariable v in GetEntitiesOfTypeInFile(config.Ast, fileName, typeof(GrapeVariable))) {
                    if (v.Name == actualVariableName && v.GetActualParent() == e) {
                        l.Add(v);
                    }
                }

                return l;
            } else if (actualQualifiedId == "base" && c != null) {
                List<GrapeVariable> l = new List<GrapeVariable>();
                foreach (GrapeVariable v in GetEntitiesOfTypeInFile(config.Ast, fileName, typeof(GrapeVariable))) {
                    if (v.Name == actualVariableName && v.GetActualParent() == GetClassWithNameFromImportedPackagesInFile(config.Ast, typeCheckingUtils.GetTypeNameForTypeAccessExpression(config, c.Inherits), fileName)) {
                        l.Add(v);
                    }
                }

                return l;
            }

            IEnumerable<GrapeEntity> packagesInFile = GetEntitiesOfTypeInFile(config.Ast, fileName, typeof(GrapePackageDeclaration));
            foreach (GrapePackageDeclaration packageDeclaration in packagesInFile) {
                foreach (KeyValuePair<string, List<string>> pair in packageFileNames) {
                    if (pair.Key == packageDeclaration.PackageName) {
                        IEnumerable<string> otherPackagesInPackage = GetOtherPackagesInPackageName(packageDeclaration.PackageName);
                        foreach (string otherPackage in otherPackagesInPackage) {
                            foreach (KeyValuePair<string, List<string>> childPair in packageFileNames) {
                                if (childPair.Key == otherPackage) {
                                    importedPackageFiles.AddRange(childPair.Value);
                                }
                            }
                        }

                        importedPackageFiles.AddRange(pair.Value);
                    }
                }
            }

            List<GrapeVariable> list = new List<GrapeVariable>();
            foreach (string importedPackageFile in importedPackageFiles) {
                IEnumerable<GrapeEntity> variables = GetEntitiesOfTypeInFile(config.Ast, importedPackageFile, typeof(GrapeVariable));
                foreach (GrapeVariable v in variables) {
                    if (v.Name == actualVariableName && (v.GetActualParent() == e || v.GetLogicalParentOfEntityType<GrapeMethod>() == e)) {
                        list.Add(v);
                    }
                }
            }

            GrapeMethod parentMethod = e.GetLogicalParentOfEntityType<GrapeMethod>();
            if (parentMethod != null) {
                foreach (GrapeVariable param in parentMethod.Parameters) {
                    if (param.Name == actualVariableName && param.GetActualParent() == parentMethod) {
                        list.Add(param);
                    }
                }
            }

            IEnumerable<GrapeEntity> packages = GetEntitiesOfType(config.Ast, typeof(GrapePackageDeclaration));
            IEnumerable<GrapeEntity> allVariables = GetEntitiesOfType(config.Ast, typeof(GrapeVariable));
            foreach (GrapePackageDeclaration packageDeclaration in packages) {
                if (packageDeclaration.PackageName == actualQualifiedId) {
                    foreach (GrapeVariable v in allVariables) {
                        if (v.Name == actualVariableName && (v.GetActualParent() == e || v.GetLogicalParentOfEntityType<GrapeMethod>() == e)) {
                            list.Add(v);
                        }
                    }
                }
            }

            foreach (string importedPackageFile in importedPackageFiles) {
                IEnumerable<GrapeEntity> fields = GetEntitiesOfTypeInFile(config.Ast, importedPackageFile, typeof(GrapeField));
                foreach (GrapeField f in fields) {
                    if (f.Field.Name == variableName && f.GetActualParent() == e) {
                        list.Add(f.Field);
                    }
                }
            }

            IEnumerable<GrapeEntity> allFields = GetEntitiesOfType(config.Ast, typeof(GrapeField));
            foreach (GrapePackageDeclaration packageDeclaration in packages) {
                if (packageDeclaration.PackageName == actualQualifiedId) {
                    foreach (GrapeField f in allFields) {
                        if (f.Field.Name == actualVariableName && f.GetActualParent() == e) {
                            list.Add(f.Field);
                        }
                    }
                }
            }

            return list;
        }
        public IEnumerable<GrapeEntity> GetMembersForExpression(GrapeCodeGeneratorConfiguration config, string variableName, GrapeEntity parent)
        {
            if (parent is GrapeExpression || parent is GrapeStatement) {
                GrapeEntity oldParent = parent;
                parent = parent.GetLogicalParentOfEntityType<GrapeMethod>();
                if (parent == null) {
                    parent = oldParent.GetLogicalParentOfEntityType<GrapeClass>();
                }
            }

            IEnumerable<GrapeVariable> variables = astUtils.GetVariablesWithNameFromImportedPackagesInFile(config, variableName, parent.FileName, parent);
            if (variables.Count() == 0) {
                variables = astUtils.GetVariablesWithNameFromImportedPackagesInFile(config, variableName, parent.FileName, parent.GetLogicalParentOfEntityType<GrapeClass>());
            }

            IEnumerable<GrapeMethod> methods = astUtils.GetMethodsWithNameFromImportedPackagesInFile(config, variableName, parent.FileName, parent.GetLogicalParentOfEntityType<GrapeClass>());
            List<GrapeEntity> list = new List<GrapeEntity>();
            list.AddRange(variables);
            list.AddRange(methods);
            return list;
        }
        public string GetMethodSignatureString(GrapeCodeGeneratorConfiguration config, string name, GrapeType returnType, List<GrapeVariable> parameters)
        {
            string result = GetTypeNameForTypeAccessExpression(config, returnType) + " " + name + "(";
            int index = 0;
            foreach (GrapeVariable parameter in parameters) {
                result += GetTypeNameForTypeAccessExpression(config, parameter.Type);
                if (index < parameters.Count - 1) {
                    result += ", ";
                }

                index++;
            }

            result += ")";
            return result;
        }
 public bool DoesExpressionResolveToType(GrapeCodeGeneratorConfiguration config, GrapeEntity parent, GrapeExpression expression, GrapeExpression type, ref string errorMessage)
 {
     return DoesExpressionResolveToType(config, parent, expression, GetTypeNameForTypeAccessExpression(config, type, ref errorMessage), ref errorMessage);
 }