func (pkg *Package) Merge(otherPackage *tp.Package) { if otherPackage == nil { return } //// Reflection would make this code cleaner: var existingTypeId int for _, someType := range otherPackage.Types { existingTypeId = pkg.GetTypeId(null.GetString(someType.Name)) if existingTypeId == -1 { pkg.Types = append(pkg.Types, someType) } } for _, function := range otherPackage.Functions { if null.GetBool(function.BuiltIn) { pkg.resolveHeader(function) } else { resolveDefinition(pkg.Package, function, "") } pkg.Package.Functions = append(pkg.Package.Functions, function) } for _, dependency := range otherPackage.Dependencies { pkg.Dependencies = append(pkg.Dependencies, dependency) } otherName := null.GetString(otherPackage.Name) pkg.Dependencies = append(pkg.Dependencies, otherName) pkg.Log.Infof("Added dependency (" + otherName + ") to " + null.GetString(pkg.Name) + "'s loaded dependencies") }
func (ctx *LinkingContext) link(objId, scopeType int) { obj := ctx.Objects[objId] if null.GetBool(obj.Linked) == false { obj.ScopeTypeId = proto.Int(scopeType) obj.Linked = proto.Bool(true) path := obj.GetName() ctx.files = append(ctx.files, path) ctx.ProcessInstruction(obj.Root, scopeType, path) ctx.files = ctx.files[:(len(ctx.files) - 1)] } else { if scopeType != int(null.GetInt32(obj.ScopeTypeId)) { ctx.error("script", "Imported a script in two different scopes! Not processing second import.") } } }
func resolveDefinition(pkg *tp.Package, fun *tp.Function, path string) { linkingContext := linker.NewLinkingContext(pkg) // pkg.Log.Infof("\t -- Resolving --\n") // pkg.Log.Infof("\t\t -- function: %v\n", fun) // Re-uses linker's logic to resolve function definitions if null.GetBool(fun.BuiltIn) == false { typeName := null.GetString(fun.ScopeType) // DON'T DO THE FOLLOWING HERE -- NEED TO RESOLVE INHERITANCE FIRST // // Make sure we're not replacing an existing function bacause it's (currently) a security risk // typeID := fun.GetScopeTypeId() // siblingFuncs := linkingContext.FunctionsIn(typeID) // // println("CHECKING FOR FRATRICIDE IN", typeName) // _, present := siblingFuncs[fun.Stub(pkg)] // if present { // msg := fmt.Sprintf("Redefining an existing function is not permitted: %s", fun.Stub(pkg)) // panic(msg) // } // // for name, sib := range siblingFuncs { // // println("\t", name, sib) // // } // ///////////////////////////////////////////////////////////////////////////// if len(typeName) != 0 { // When I pass in functions from the inheritance resolver, they're typeId is already set fun.ScopeTypeId = pkg.GetProtoTypeId(fun.ScopeType) fun.ScopeType = nil } localScope := make(linker.LocalDef, len(fun.Args)) // fun.ReturnTypeId = pkg.GetProtoTypeId(fun.ReturnType) for _, arg := range fun.Args { argTypeName := arg.TypeString var argTypeId int if argTypeName != nil { // Similar deal. Input functions from inheritance resolution already have ids set arg.TypeId = pkg.GetProtoTypeId(arg.TypeString) //println("Processing %", null.GetString(arg.Name)) argTypeId = pkg.GetTypeId(null.GetString(arg.TypeString)) arg.TypeString = nil } else { argTypeId = int(null.GetInt32(arg.TypeId)) } localScope[null.GetString(arg.Name)] = argTypeId } //pkg.Log.Infof("Some insitruction: %v, %s", fun.Instruction, null.GetString(fun.Name) ) scopeTypeId := int(null.GetInt32(fun.ScopeTypeId)) //pkg.Log.Infof("\t\t -- opening scope type : %v\n", scopeTypeId) returnType := linkingContext.ProcessInstructionWithLocalScope(fun.Instruction, scopeTypeId, localScope, *fun.Name, path, false) if linkingContext.HasErrors() { message := "" for _, msg := range linkingContext.Errors { message = message + "\n" + msg } panic(message) } fun.ReturnTypeId = proto.Int32(int32(returnType)) if fun.Instruction != nil { fun.Instruction.IterateAll(func(ins *tp.Instruction) { if *ins.Type == constants.Instruction_FUNCTION_CALL { if null.GetString(ins.Value) == "yield" { fun.OpensTypeId = ins.YieldTypeId } } }) } } //pkg.Log.Infof("\t\t -- done --\n") }