当前位置: 首页>>代码示例>>Golang>>正文


Golang GraphNode.TryGetIncomingNode方法代码示例

本文整理汇总了Golang中github.com/serulian/compiler/compilergraph.GraphNode.TryGetIncomingNode方法的典型用法代码示例。如果您正苦于以下问题:Golang GraphNode.TryGetIncomingNode方法的具体用法?Golang GraphNode.TryGetIncomingNode怎么用?Golang GraphNode.TryGetIncomingNode使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在github.com/serulian/compiler/compilergraph.GraphNode的用法示例。


在下文中一共展示了GraphNode.TryGetIncomingNode方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。

示例1: scopeAssignedValue

// scopeAssignedValue scopes a named assigned value exported into the context.
func (sb *scopeBuilder) scopeAssignedValue(node compilergraph.GraphNode, context scopeContext) proto.ScopeInfo {
	// If the assigned value's name is _, then it is anonymous scope.
	if node.Get(parser.NodeNamedValueName) == ANONYMOUS_REFERENCE {
		return newScope().ForAnonymousScope(sb.sg.tdg).GetScope()
	}

	// If the assigned value is under a rejection, then it is always an error (but nullable, as it
	// may not be present always).
	if _, ok := node.TryGetIncomingNode(parser.NodeAssignedRejection); ok {
		return newScope().Valid().Assignable(sb.sg.tdg.ErrorTypeReference().AsNullable()).GetScope()
	}

	// Otherwise, the value is the assignment of the parent statement's expression.
	parentNode := node.GetIncomingNode(parser.NodeAssignedDestination)
	switch parentNode.Kind() {
	case parser.NodeTypeResolveStatement:
		// The assigned value exported by a resolve statement has the type of its expression.
		exprScope := sb.getScope(parentNode.GetNode(parser.NodeResolveStatementSource), context)
		if !exprScope.GetIsValid() {
			return newScope().Invalid().GetScope()
		}

		// If the parent node has a rejection, then the expression may be null.
		exprType := exprScope.ResolvedTypeRef(sb.sg.tdg)
		if _, ok := parentNode.TryGetNode(parser.NodeAssignedRejection); ok {
			exprType = exprType.AsNullable()
		}

		return newScope().Valid().Assignable(exprType).GetScope()

	default:
		panic(fmt.Sprintf("Unknown node exporting an assigned value: %v", parentNode.Kind()))
		return newScope().Invalid().GetScope()
	}
}
开发者ID:Serulian,项目名称:compiler,代码行数:36,代码来源:scope_statements.go

示例2: scopeKeywordNotExpression

// scopeKeywordNotExpression scopes a keyword not expression in the SRG.
func (sb *scopeBuilder) scopeKeywordNotExpression(node compilergraph.GraphNode, context scopeContext) proto.ScopeInfo {
	// Check for 'is not null' case.
	parentExpr, hasParentExpr := node.TryGetIncomingNode(parser.NodeBinaryExpressionRightExpr)
	if hasParentExpr && parentExpr.Kind() == parser.NodeIsComparisonExpression {
		if node.GetNode(parser.NodeUnaryExpressionChildExpr).Kind() != parser.NodeNullLiteralExpression {
			sb.decorateWithError(node, "Expression under an 'is not' must be 'null'")
			return newScope().Invalid().GetScope()
		}
		return newScope().Valid().GetScope()
	}

	// Check for normal bool-eable.
	return sb.scopeUnaryExpression(node, "bool", parser.NodeUnaryExpressionChildExpr, context).GetScope()
}
开发者ID:Serulian,项目名称:compiler,代码行数:15,代码来源:scope_op_expr.go

示例3: scopeIdentifierExpression

// scopeIdentifierExpression scopes an identifier expression in the SRG.
func (sb *scopeBuilder) scopeIdentifierExpression(node compilergraph.GraphNode, context scopeContext) proto.ScopeInfo {
	name := node.Get(parser.NodeIdentifierExpressionName)
	if name == ANONYMOUS_REFERENCE {
		// Make sure this node is under an assignment of some kind.
		var found = false
		for _, predicate := range ALLOWED_ANONYMOUS {
			if _, ok := node.TryGetIncomingNode(predicate); ok {
				found = true
				break
			}
		}

		if !found {
			sb.decorateWithError(node, "Anonymous identifier '_' cannot be used as a value")
			return newScope().Invalid().GetScope()
		}

		return newScope().ForAnonymousScope(sb.sg.tdg).GetScope()
	}

	// Lookup the name given, starting at the location of the current node.
	namedScope, rerr := sb.lookupNamedScope(name, node)
	if rerr != nil {
		sb.decorateWithError(node, "%v", rerr)
		return newScope().Invalid().GetScope()
	}

	// Ensure that the named scope has a valid type.
	if !namedScope.IsValid(context) {
		return newScope().Invalid().GetScope()
	}

	// Warn if we are accessing an assignable value under an async function, as it will be executing
	// in a different context.
	if namedScope.IsAssignable() && namedScope.UnderModule() {
		srgImpl, found := context.getParentContainer(sb.sg.srg)
		if found && srgImpl.ContainingMember().IsAsyncFunction() {
			sb.decorateWithWarning(node, "%v '%v' is defined outside the async function and will therefore be unique for each call to this function", namedScope.Title(), name)
		}
	}

	context.staticDependencyCollector.checkNamedScopeForDependency(namedScope)
	return newScope().ForNamedScope(namedScope, context).GetScope()
}
开发者ID:Serulian,项目名称:compiler,代码行数:45,代码来源:scope_name_expr.go

示例4: buildNamedAccess

// buildNamedAccess builds the CodeDOM for a member access expression.
func (db *domBuilder) buildNamedAccess(node compilergraph.GraphNode, name string, childExprNode *compilergraph.GraphNode) codedom.Expression {
	scope, _ := db.scopegraph.GetScope(node)
	namedReference, hasNamedReference := db.scopegraph.GetReferencedName(scope)

	// Reference to an unknown name or a nullable member access must be a dynamic access.
	if !hasNamedReference || node.Kind() == parser.NodeNullableMemberAccessExpression {
		return codedom.DynamicAccess(db.buildExpression(*childExprNode), name, node)
	}

	// Reference to a local name is a var or parameter.
	if namedReference.IsLocal() {
		return codedom.LocalReference(namedReference.Name(), node)
	}

	// Check for a reference to a type.
	if typeRef, isType := namedReference.Type(); isType {
		return codedom.StaticTypeReference(typeRef, node)
	}

	// Check for a reference to a member.
	if memberRef, isMember := namedReference.Member(); isMember {
		// If the member is under a child expression, build as an access expression.
		if childExprNode != nil {
			childExpr := db.buildExpression(*childExprNode)

			_, underFuncCall := node.TryGetIncomingNode(parser.NodeFunctionCallExpressionChildExpr)
			isAliasedFunctionReference := scope.ResolvedTypeRef(db.scopegraph.TypeGraph()).HasReferredType(db.scopegraph.TypeGraph().FunctionType())

			if isAliasedFunctionReference && !underFuncCall {
				return codedom.DynamicAccess(childExpr, memberRef.Name(), node)
			} else {
				return codedom.MemberReference(childExpr, memberRef, node)
			}
		} else {
			// This is a direct access of a static member. Generate an access under the module.
			return codedom.StaticMemberReference(memberRef, db.scopegraph.TypeGraph().AnyTypeReference(), node)
		}
	}

	panic("Unknown kind of named access")
	return nil
}
开发者ID:Serulian,项目名称:compiler,代码行数:43,代码来源:build_access_expr.go

示例5: findAddedNameInScope

// findAddedNameInScope finds the {parameter, with, loop, var} node exposing the given name, if any.
func (g *SRG) findAddedNameInScope(name string, node compilergraph.GraphNode) (compilergraph.GraphNode, bool) {
	nodeSource := node.Get(parser.NodePredicateSource)
	nodeStartIndex := node.GetValue(parser.NodePredicateStartRune).Int()

	// Note: This filter ensures that the name is accessible in the scope of the given node by checking that
	// the node adding the name contains the given node.
	containingFilter := func(q compilergraph.GraphQuery) compilergraph.Query {
		startRune := node.GetValue(parser.NodePredicateStartRune).Int()
		endRune := node.GetValue(parser.NodePredicateEndRune).Int()

		return q.
			In(parser.NodePredicateTypeMemberParameter,
				parser.NodeLambdaExpressionInferredParameter,
				parser.NodeLambdaExpressionParameter,
				parser.NodePredicateTypeMemberGeneric,
				parser.NodeStatementNamedValue,
				parser.NodeAssignedDestination,
				parser.NodeAssignedRejection,
				parser.NodePredicateChild,
				parser.NodeStatementBlockStatement).
			InIfKind(parser.NodeStatementBlockStatement, parser.NodeTypeResolveStatement).
			HasWhere(parser.NodePredicateStartRune, compilergraph.WhereLTE, startRune).
			HasWhere(parser.NodePredicateEndRune, compilergraph.WhereGTE, endRune)
	}

	nit := g.layer.StartQuery(name).
		In("named").
		Has(parser.NodePredicateSource, nodeSource).
		IsKind(parser.NodeTypeParameter, parser.NodeTypeNamedValue, parser.NodeTypeAssignedValue,
			parser.NodeTypeVariableStatement, parser.NodeTypeLambdaParameter, parser.NodeTypeGeneric).
		FilterBy(containingFilter).
		BuildNodeIterator(parser.NodePredicateStartRune, parser.NodePredicateEndRune)

	// Sort the nodes found by location and choose the closest node.
	var results = make(scopeResultNodes, 0)
	for nit.Next() {
		node := nit.Node()
		startIndex := nit.GetPredicate(parser.NodePredicateStartRune).Int()

		// If the node is a variable statement or assigned value, we have do to additional checks
		// (since they are not block scoped but rather statement scoped).
		if node.Kind() == parser.NodeTypeVariableStatement || node.Kind() == parser.NodeTypeAssignedValue {
			endIndex := nit.GetPredicate(parser.NodePredicateEndRune).Int()
			if node.Kind() == parser.NodeTypeAssignedValue {
				if parentNode, ok := node.TryGetIncomingNode(parser.NodeAssignedDestination); ok {
					endIndex = parentNode.GetValue(parser.NodePredicateEndRune).Int()
				} else if parentNode, ok := node.TryGetIncomingNode(parser.NodeAssignedRejection); ok {
					endIndex = parentNode.GetValue(parser.NodePredicateEndRune).Int()
				} else {
					panic("Missing assigned parent")
				}
			}

			// Check that the startIndex of the variable statement is <= the startIndex of the parent node
			if startIndex > nodeStartIndex {
				continue
			}

			// Ensure that the scope starts after the end index of the variable. Otherwise, the variable
			// name could be used in its initializer expression (which is expressly disallowed).
			if nodeStartIndex <= endIndex {
				continue
			}
		}

		results = append(results, scopeResultNode{node, startIndex})
	}

	if len(results) == 1 {
		// If there is a single result, return it.
		return results[0].node, true
	} else if len(results) > 1 {
		// Otherwise, sort the list by startIndex and choose the one closest to the scope node.
		sort.Sort(results)
		return results[0].node, true
	}

	return compilergraph.GraphNode{}, false
}
开发者ID:Serulian,项目名称:compiler,代码行数:80,代码来源:scopename.go

示例6: scopeFunctionCallExpression


//.........这里部分代码省略.........
	}

	getDescription := func() string {
		if !hasNamedNode {
			return ""
		}

		return fmt.Sprintf("on %v %v ", namedNode.Title(), namedNode.Name())
	}

	// Ensure the child expression has type function.
	childType := childScope.ResolvedTypeRef(sb.sg.tdg)
	if !childType.IsDirectReferenceTo(sb.sg.tdg.FunctionType()) {
		// If the child type is a function, but nullable, only allow it to be called if the type
		// is a result of a null access expression. This is a special case to allow writing code
		// such as `foo?.bar()` easier, without allowing for random `someNullableFunc()` to be
		// called.
		//
		// TODO: It might be a good idea to revisit this decision if we find `someNullableFunc()` to
		// be a useful pattern as well.
		if !childType.HasReferredType(sb.sg.tdg.FunctionType()) ||
			childExpr.Kind() != parser.NodeNullableMemberAccessExpression {
			sb.decorateWithError(node, "Cannot invoke function call on non-function '%v'.", childType)
			return newScope().Invalid().GetScope()
		}
	}

	// Find the starting index of the nullable parameters. Once all parameters are nullable,
	// they are considered optional.
	var nonOptionalIndex = -1
	childParameters := childType.Parameters()
	for parameterIndex, parameterType := range childParameters {
		if !parameterType.NullValueAllowed() {
			nonOptionalIndex = parameterIndex
		}
	}

	// Ensure that the parameters of the function call match those of the child type.
	var index = -1
	ait := node.StartQuery().
		Out(parser.NodeFunctionCallArgument).
		BuildNodeIterator()

	var isValid = true
	for ait.Next() {
		index = index + 1

		// Resolve the scope of the argument.
		argumentScope := sb.getScope(ait.Node(), context)
		if !argumentScope.GetIsValid() {
			isValid = false
			nonOptionalIndex = index
			continue
		}

		if index < len(childParameters) {
			// Ensure the type of the argument matches the parameter.
			argumentType := argumentScope.ResolvedTypeRef(sb.sg.tdg)
			serr, exception := argumentType.CheckSubTypeOfWithExceptions(childParameters[index], typegraph.AllowNominalWrappedForData)
			if serr != nil {
				sb.decorateWithError(ait.Node(), "Parameter #%v %sexpects type %v: %v", index+1, getDescription(), childParameters[index], serr)
				isValid = false
			}

			// If a nominally-wrapped value was used in place of an argument that expects its data type, then
			// mark the expression as being a shortcut that needs unwrapping during generation.
			if exception == typegraph.AllowNominalWrappedForData {
				sb.decorateWithSecondaryLabel(ait.Node(), proto.ScopeLabel_NOMINALLY_SHORTCUT_EXPR)
			}
		}
	}

	if index < nonOptionalIndex {
		sb.decorateWithError(node, "Function call %sexpects %v non-optional arguments, found %v", getDescription(), nonOptionalIndex+1, index+1)
		return newScope().Invalid().GetScope()
	}

	if index >= len(childParameters) {
		sb.decorateWithError(node, "Function call %sexpects %v arguments, found %v", getDescription(), len(childParameters), index+1)
		return newScope().Invalid().GetScope()
	}

	var returnType = childType.Generics()[0]
	if childType.IsNullable() {
		returnType = returnType.AsNullable()
	}

	// Check for an awaitable return type. If found and this call is not under an assignment or
	// arrow, warn.
	if isValid && returnType.IsDirectReferenceTo(sb.sg.tdg.AwaitableType()) {
		if !returnType.Generics()[0].IsVoid() {
			if _, underStatement := node.TryGetIncomingNode(parser.NodeExpressionStatementExpression); underStatement {
				sb.decorateWithWarning(node, "Returned Awaitable resolves a value of type %v which is not handled", returnType.Generics()[0])
			}
		}
	}

	// The function call returns the first generic of the function.
	return newScope().IsValid(isValid).Resolving(returnType).GetScope()
}
开发者ID:Serulian,项目名称:compiler,代码行数:101,代码来源:scope_op_expr.go

示例7: inferLambdaParameterTypes

// inferLambdaParameterTypes performs type inference to determine the types of the parameters of the
// given lambda expression (if necessary).
//
// Forms supported for inference:
//
// var someVar = (a, b) => someExpr
// someVar(1, 2)
//
// var<function<void>(...)> = (a, b) => someExpr
//
// ((a, b) => someExpr)(1, 2)
func (sb *scopeBuilder) inferLambdaParameterTypes(node compilergraph.GraphNode, context scopeContext) {
	// If the lambda has no inferred parameters, nothing more to do.
	if _, ok := node.TryGetNode(parser.NodeLambdaExpressionInferredParameter); !ok {
		return
	}

	// Otherwise, collect the names and positions of the inferred parameters.
	pit := node.StartQuery().
		Out(parser.NodeLambdaExpressionInferredParameter).
		BuildNodeIterator()

	var inferenceParameters = make([]compilergraph.GraphNode, 0)
	for pit.Next() {
		inferenceParameters = append(inferenceParameters, pit.Node())
	}

	getInferredTypes := func() ([]typegraph.TypeReference, bool) {
		// Check if the lambda expression is under a function call expression. If so, we use the types of
		// the parameters.
		parentCall, hasParentCall := node.TryGetIncomingNode(parser.NodeFunctionCallExpressionChildExpr)
		if hasParentCall {
			return sb.getFunctionCallArgumentTypes(parentCall, context), true
		}

		// Check if the lambda expression is under a variable declaration. If so, we try to infer from
		// either its declared type or its use(s).
		parentVariable, hasParentVariable := node.TryGetIncomingNode(parser.NodeVariableStatementExpression)
		if !hasParentVariable {
			return make([]typegraph.TypeReference, 0), false
		}

		// Check if the parent variable has a declared type of function. If so, then we simply
		// use the declared parameter types.
		declaredType, hasDeclaredType := sb.getDeclaredVariableType(parentVariable)
		if hasDeclaredType && declaredType.IsDirectReferenceTo(sb.sg.tdg.FunctionType()) {
			return declaredType.Parameters(), true
		}

		// Otherwise, we find all references of the variable under the parent scope that are,
		// themselves, under a function call, and intersect the types of arguments found.
		parentVariableName := parentVariable.Get(parser.NodeVariableStatementName)
		parentBlock, hasParentBlock := parentVariable.TryGetIncomingNode(parser.NodeStatementBlockStatement)
		if !hasParentBlock {
			return make([]typegraph.TypeReference, 0), false
		}

		var inferredTypes = make([]typegraph.TypeReference, 0)
		rit := sb.sg.srg.FindReferencesInScope(parentVariableName, parentBlock)
		for rit.Next() {
			funcCall, hasFuncCall := rit.Node().TryGetIncomingNode(parser.NodeFunctionCallExpressionChildExpr)
			if !hasFuncCall {
				continue
			}

			inferredTypes = sb.sg.tdg.IntersectTypes(inferredTypes, sb.getFunctionCallArgumentTypes(funcCall, context))
		}

		return inferredTypes, true
	}

	// Resolve the inferred types and decorate the parameters with them (if any).
	inferredTypes, hasInferredTypes := getInferredTypes()
	if hasInferredTypes {
		for index, inferenceParameter := range inferenceParameters {
			var inferredType = sb.sg.tdg.AnyTypeReference()
			if index < len(inferredTypes) {
				if !inferredTypes[index].IsVoid() {
					inferredType = inferredTypes[index]
				}
			}

			sb.inferredParameterTypes.Set(string(inferenceParameter.NodeId), inferredType)
			sb.modifier.Modify(inferenceParameter).DecorateWithTagged(NodePredicateInferredType, inferredType)
		}
	} else {
		for _, inferenceParameter := range inferenceParameters {
			sb.inferredParameterTypes.Set(string(inferenceParameter.NodeId), sb.sg.tdg.AnyTypeReference())
			sb.modifier.Modify(inferenceParameter).DecorateWithTagged(NodePredicateInferredType, sb.sg.tdg.AnyTypeReference())
		}
	}
}
开发者ID:Serulian,项目名称:compiler,代码行数:92,代码来源:scope_lambda_expr.go


注:本文中的github.com/serulian/compiler/compilergraph.GraphNode.TryGetIncomingNode方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。