Get codeOffset/codeLength through LazyNode.

So, that it works whether nodes are lazy or full.

R=brianwilkerson@google.com

Change-Id: I4c8916f05b0f73a6f825d4c15e45dade5f702582
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/101881
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index 9f7fd21..b6b54c2 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -109,6 +109,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readDocumentationComment(
     AstBinaryReader reader,
     ClassDeclaration node,
@@ -214,6 +236,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readDocumentationComment(
     AstBinaryReader reader,
     ClassTypeAlias node,
@@ -289,6 +333,44 @@
   }
 }
 
+class LazyCompilationUnit {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  LazyCompilationUnit(this.data);
+
+  static LazyCompilationUnit get(CompilationUnit node) {
+    return node.getProperty(_key);
+  }
+
+  static int getCodeLength(
+    AstBinaryReader reader,
+    CompilationUnit node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    CompilationUnit node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
+  static void setData(CompilationUnit node, LinkedNode data) {
+    node.setProperty(_key, LazyCompilationUnit(data));
+  }
+}
+
 class LazyConstructorDeclaration {
   static const _key = 'lazyAst';
 
@@ -307,6 +389,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    ConstructorDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    ConstructorDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readBody(
     AstBinaryReader reader,
     ConstructorDeclaration node,
@@ -498,6 +602,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    EnumDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    EnumDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readConstants(
     AstBinaryReader reader,
     EnumDeclaration node,
@@ -611,6 +737,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    FormalParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    FormalParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static DartType getType(
     AstBinaryReader reader,
     FormalParameter node,
@@ -628,7 +776,7 @@
 
   static TopLevelInferenceError getTypeInferenceError(FormalParameter node) {
     var lazy = get(node);
-    if (!lazy._hasTypeInferenceError) {
+    if (lazy != null && !lazy._hasTypeInferenceError) {
       var error = lazy.data.topLevelTypeInferenceError;
       LazyAst.setTypeInferenceError(node, error);
       lazy._hasTypeInferenceError = true;
@@ -723,6 +871,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    FunctionDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    FunctionDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static DartType getReturnType(
     AstBinaryReader reader,
     FunctionDeclaration node,
@@ -860,6 +1030,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static bool getHasSelfReference(FunctionTypeAlias node) {
     return node.getProperty(_hasSelfReferenceKey);
   }
@@ -1020,6 +1212,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    GenericTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    GenericTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static bool getHasSelfReference(GenericTypeAlias node) {
     return node.getProperty(_hasSelfReferenceKey);
   }
@@ -1093,6 +1307,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static DartType getReturnType(
     AstBinaryReader reader,
     MethodDeclaration node,
@@ -1230,6 +1466,28 @@
     return lazy;
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    MixinDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    MixinDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static void readDocumentationComment(
     AstBinaryReader reader,
     MixinDeclaration node,
@@ -1362,6 +1620,28 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    TypeParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    return node.length;
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    TypeParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    return node.offset;
+  }
+
   static DartType getDefaultType(AstBinaryReader reader, TypeParameter node) {
     var lazy = get(node);
     if (lazy != null && !lazy._hasDefaultType) {
@@ -1416,6 +1696,38 @@
     return node.getProperty(_key);
   }
 
+  static int getCodeLength(
+    AstBinaryReader reader,
+    VariableDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeLength;
+    }
+    VariableDeclarationList parent = node.parent;
+    if (parent.variables[0] == node) {
+      return node.end - parent.offset;
+    } else {
+      return node.end - node.offset;
+    }
+  }
+
+  static int getCodeOffset(
+    AstBinaryReader reader,
+    VariableDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      return lazy.data.codeOffset;
+    }
+    VariableDeclarationList parent = node.parent;
+    if (parent.variables[0] == node) {
+      return parent.offset;
+    } else {
+      return node.offset;
+    }
+  }
+
   static DartType getType(
     AstBinaryReader reader,
     VariableDeclaration node,
@@ -1434,7 +1746,7 @@
   static TopLevelInferenceError getTypeInferenceError(
       VariableDeclaration node) {
     var lazy = get(node);
-    if (!lazy._hasTypeInferenceError) {
+    if (lazy != null && !lazy._hasTypeInferenceError) {
       var error = lazy.data.topLevelTypeInferenceError;
       LazyAst.setTypeInferenceError(node, error);
       lazy._hasTypeInferenceError = true;
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index ac704b4..5890831 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -140,62 +140,62 @@
 
   int getCodeLength(AstNode node) {
     if (node is ClassDeclaration) {
-      return LazyClassDeclaration.get(node).data.codeLength;
+      return LazyClassDeclaration.getCodeLength(_astReader, node);
     } else if (node is ClassTypeAlias) {
-      return LazyClassTypeAlias.get(node).data.codeLength;
+      return LazyClassTypeAlias.getCodeLength(_astReader, node);
     } else if (node is CompilationUnit) {
-      return data.node.codeLength;
+      return node.length;
     } else if (node is ConstructorDeclaration) {
-      return LazyConstructorDeclaration.get(node).data.codeLength;
+      return LazyConstructorDeclaration.getCodeLength(_astReader, node);
     } else if (node is EnumDeclaration) {
-      return LazyEnumDeclaration.get(node).data.codeLength;
+      return LazyEnumDeclaration.getCodeLength(_astReader, node);
     } else if (node is FormalParameter) {
-      return LazyFormalParameter.get(node).data.codeLength;
+      return LazyFormalParameter.getCodeLength(_astReader, node);
     } else if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.get(node).data.codeLength;
+      return LazyFunctionDeclaration.getCodeLength(_astReader, node);
     } else if (node is FunctionTypeAliasImpl) {
-      return LazyFunctionTypeAlias.get(node).data.codeLength;
+      return LazyFunctionTypeAlias.getCodeLength(_astReader, node);
     } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.get(node).data.codeLength;
+      return LazyGenericTypeAlias.getCodeLength(_astReader, node);
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.get(node).data.codeLength;
+      return LazyMethodDeclaration.getCodeLength(_astReader, node);
     } else if (node is MixinDeclaration) {
-      return LazyMixinDeclaration.get(node).data.codeLength;
+      return LazyMixinDeclaration.getCodeLength(_astReader, node);
     } else if (node is TypeParameter) {
-      return LazyTypeParameter.get(node).data.codeLength;
+      return LazyTypeParameter.getCodeLength(_astReader, node);
     } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.get(node).data.codeLength;
+      return LazyVariableDeclaration.getCodeLength(_astReader, node);
     }
     throw UnimplementedError('${node.runtimeType}');
   }
 
   int getCodeOffset(AstNode node) {
     if (node is ClassDeclaration) {
-      return LazyClassDeclaration.get(node).data.codeOffset;
+      return LazyClassDeclaration.getCodeOffset(_astReader, node);
     } else if (node is ClassTypeAlias) {
-      return LazyClassTypeAlias.get(node).data.codeOffset;
+      return LazyClassTypeAlias.getCodeOffset(_astReader, node);
     } else if (node is CompilationUnit) {
-      return data.node.codeOffset;
+      return 0;
     } else if (node is ConstructorDeclaration) {
-      return LazyConstructorDeclaration.get(node).data.codeOffset;
+      return LazyConstructorDeclaration.getCodeOffset(_astReader, node);
     } else if (node is EnumDeclaration) {
-      return LazyEnumDeclaration.get(node).data.codeOffset;
+      return LazyEnumDeclaration.getCodeOffset(_astReader, node);
     } else if (node is FormalParameter) {
-      return LazyFormalParameter.get(node).data.codeOffset;
+      return LazyFormalParameter.getCodeOffset(_astReader, node);
     } else if (node is FunctionDeclaration) {
-      return LazyFunctionDeclaration.get(node).data.codeOffset;
+      return LazyFunctionDeclaration.getCodeOffset(_astReader, node);
     } else if (node is FunctionTypeAliasImpl) {
-      return LazyFunctionTypeAlias.get(node).data.codeOffset;
+      return LazyFunctionTypeAlias.getCodeOffset(_astReader, node);
     } else if (node is GenericTypeAlias) {
-      return LazyGenericTypeAlias.get(node).data.codeOffset;
+      return LazyGenericTypeAlias.getCodeOffset(_astReader, node);
     } else if (node is MethodDeclaration) {
-      return LazyMethodDeclaration.get(node).data.codeOffset;
+      return LazyMethodDeclaration.getCodeOffset(_astReader, node);
     } else if (node is MixinDeclaration) {
-      return LazyMixinDeclaration.get(node).data.codeOffset;
+      return LazyMixinDeclaration.getCodeOffset(_astReader, node);
     } else if (node is TypeParameter) {
-      return LazyTypeParameter.get(node).data.codeOffset;
+      return LazyTypeParameter.getCodeOffset(_astReader, node);
     } else if (node is VariableDeclaration) {
-      return LazyVariableDeclaration.get(node).data.codeOffset;
+      return LazyVariableDeclaration.getCodeOffset(_astReader, node);
     }
     throw UnimplementedError('${node.runtimeType}');
   }