Beispiel #1
0
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")
}
Beispiel #2
0
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.")
		}
	}
}
Beispiel #3
0
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")
}