本文整理汇总了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()
}
}
示例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()
}
示例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()
}
示例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
}
示例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
}
示例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()
}
示例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())
}
}
}